home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / amigamesa.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  33KB  |  1,375 lines

  1. /* $Id: AmigaMesa.c,v 1.7 Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Library General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Library General Public
  18.  * License along with this library; if not, write to the Free
  19.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. /*
  23. $Log: AmigaMesa.c,v1.6 $
  24.  * Revision 1.7  1996/05/21  23:08:42  StefanZ
  25.  * A few bug and enforcer fixes
  26.  *
  27.  * Revision 1.6  1996/04/29  22:14:31  StefanZ
  28.  * BugFixes reported by by Daniel Jönsson
  29.  *
  30.  * Revision 1.5  1996/03/14  23:54:33  StefanZ
  31.  * Doublebuffer & Tmprastport seams to work (big speed improvment)
  32.  * a fastpolydraw is also implemented
  33.  *
  34.  * Revision 1.4  1996/03/07  16:55:04  StefanZ
  35.  * Much of the code works now (RGB mode is simulated) Doublebuffers... (didn't work)
  36.  *
  37.  * Revision 1.3  1996/02/29  02:12:45  StefanZ
  38.  * First sight of colors (even the right ones) maglight.c works
  39.  *
  40.  * Revision 1.2  1996/02/25  13:11:16  StefanZ
  41.  * First working version. Draws everything with the same color
  42.  * (Colormaping is now urgent needed)
  43.  *
  44.  * Revision 1.1  1996/02/23  22:01:15  StefanZ
  45.  * Made changes to match latest version of ddsample 1.5
  46.  *
  47.  * Revision 1.0  1996/02/21  11:01:15  StefanZ
  48.  * File created from ddsample.c ver 1.3 and amesa.c ver 1.5
  49.  * in a brave atempt to rebuild the amiga version
  50.  *
  51.  */
  52.  
  53. /*
  54. TODO:
  55. Have two colortables in dubbelduffering so that it dont get deallocated when showing. (memory saving)
  56. Dynamic allocate the vectorbuffer for polydrawing. (Speed improvment)
  57. Draw lines insted off pixles in Write_monocolor_span.(speed improvment)
  58. Use writepixelarray in sted of WritePixel in write_index_span & write_color_span. (speed improvment)
  59.  
  60. Check make_temp_Rport and dont use areafill if it fail's.
  61.  
  62. IDEAS:
  63.  Make drawing on a Cyber-GFX in full color. (If someone gave me a 
  64.  gfx-card I would speed up on this :)
  65.  Make the gl a sharedlibrary. (Have ben started)
  66.  
  67.  
  68. */
  69.  
  70.  
  71. /*
  72.  * Note that you'll usually have to flip Y coordinates since Mesa's
  73.  * window coordinates start at the bottom and increase upward.  Most
  74.  * window system's Y-axis increases downward
  75.  *
  76.  * See dd.h for more device driver info.
  77.  * See the other device driver implementations for ideas.
  78.  *
  79.  * The Makefile should compile this module along with the rest of
  80.  * the core Mesa library.
  81.  */
  82.  
  83.  
  84. #include <exec/memory.h>
  85. #include <proto/exec.h>
  86. #include <proto/intuition.h>
  87. #include <proto/graphics.h>
  88.  
  89.  
  90.  
  91.  
  92. #include <stdlib.h>
  93. #include <stdio.h>
  94. #include "gl/AmigaMesa.h"
  95. #include "context.h"
  96. #include "dd.h"
  97. #include "xform.h"
  98. #include "vb.h"
  99.  
  100. #define MAX_POLYGON 300
  101.  
  102.  
  103.  
  104.  
  105. /**********************************************************************/
  106. /*****              Internal Data                                 *****/
  107. /**********************************************************************/
  108. struct amigamesa_context * Current = NULL;
  109.  
  110.  
  111. /**********************************************************************/
  112. /*****              Some Usefull code                             *****/
  113. /**********************************************************************/
  114.  
  115.  
  116.  
  117. static struct RastPort *make_rastport( int width, int height, int depth );
  118. static void destroy_rastport( struct RastPort *rp );
  119. static BOOL make_temp_raster( struct RastPort *rp );
  120. static void destroy_temp_raster( struct RastPort *rp );
  121. static void AllocOneLine(struct amigamesa_context *AmigaMesaCreateContext);
  122. static void FreeOneLine(struct amigamesa_context *AmigaMesaCreateContext);
  123.  
  124. #define c8to32(x) (((((((x)<<8)|(x))<<8)|(x))<<8)|(x))
  125.  
  126. __inline int RGBA(GLubyte r,GLubyte g,GLubyte b,GLubyte a)
  127.     {
  128.     int pen;
  129.     
  130. /*printf("RGBA(%d,%d,%d,%d)",r,g,b,a);getchar();*/
  131.     pen=ObtainBestPen(Current->window->WScreen->ViewPort.ColorMap,
  132.             c8to32((ULONG)r),c8to32((ULONG)g),c8to32((ULONG)b),
  133.             OBP_Precision,PRECISION_GUI,TAG_DONE);
  134.     if(!(pen==-1))
  135.         {
  136.         Current->mypen[pen]+=1;
  137.         }
  138.     else
  139.         {
  140.         pen=FindColor(Current->window->WScreen->ViewPort.ColorMap,
  141.                                     c8to32((ULONG)r),c8to32((ULONG)g),c8to32((ULONG)b),-1); 
  142.                                     /* If all pen is no sharable  take one */
  143. /*    kprintf("(no sharable pen)\n",pen);*/
  144.  
  145.         }
  146. /*printf("=%d\n",pen);*/
  147.     return pen;
  148.     }
  149.     
  150.  
  151. __inline GLint FIXx(GLint x)
  152.     {
  153.     return(Current->left + x);
  154.     }
  155.  
  156. __inline GLint FIXy(GLint y)
  157.     {
  158.     return(Current->bottom - y);
  159.     }
  160.  
  161.  
  162. /**********************************************************************/
  163. /*****              Miscellaneous device driver funcs             *****/
  164. /**********************************************************************/
  165.  
  166. static void afinish( void )
  167. {
  168.    /* implements glFinish if possible */
  169.  
  170. }
  171.  
  172.  
  173.  
  174. static void aflush( void )
  175. {
  176.    /* implements glFlush if possible */
  177.  
  178. }
  179.  
  180.  
  181.  
  182. static void aclear_index( GLuint index )
  183. {
  184.    /* implement glClearIndex */
  185.    /* usually just save the value in the context struct */
  186. /*printf("aclear_index=glClearIndex=%d\n",index);*/
  187.     Current->clearpixel=Current->penconv[index];
  188. }
  189.  
  190.  
  191.  
  192. static void aclear_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  193. {
  194.    /* implement glClearColor */
  195.    /* color components are floats in [0,1] */
  196.    /* usually just save the value in the context struct */
  197. /*printf("aclear_color=glClearColor(%d,%d,%d,%d)\n",r,g,b,a);*/
  198.     /* @@@ TODO FREE COLOR IF NOT USED */
  199.     Current->clearpixel=RGBA(r,g,b,a);
  200. }
  201.  
  202.  
  203.  
  204. static void aclear( GLboolean all, GLint x, GLint y, GLint width, GLint height )
  205. {
  206. /*
  207.  * Clear the specified region of the color buffer using the clear color
  208.  * or index as specified by one of the two functions above.
  209.  * If all==GL_TRUE, clear whole buffer
  210.  */
  211. /*printf("aclear(%d,%d,%d,%d,%d)\n",all,x,y,width,height);*/
  212.     SetAPen(Current->rp,Current->clearpixel);
  213.     if(all)
  214.         {
  215.  
  216.         RectFill(Current->rp,Current->left,Current->window->BorderTop,Current->left+Current->width-1,Current->bottom);
  217.  
  218.         if (Current->rgb_flag)
  219.             {
  220.             int I;
  221.             for(I=0;I<=255;I++)  /* Dealocate pens is in RGB mode */
  222.                 {
  223.                 while (Current->mypen[I]!=0)            /* TODO This may free some others pen also */
  224.                     {
  225.                     Current->mypen[I]-=1;
  226.                     ReleasePen(Current->window->WScreen->ViewPort.ColorMap,I);
  227.                     }
  228.                 }
  229.             }
  230.         }
  231.     else
  232.         {
  233.         if(Current->rp!=0)
  234.             {
  235. /*            printf("RectFill(0x%x,%d,%d,%d,%d)\n",Current->rp,FIXx(x),FIXy(y)-height,width,FIXy(y));*/
  236.             RectFill(Current->rp,FIXx(x),FIXy(y)-height,width,FIXy(y));
  237.             }
  238.         else
  239.             printf("Serius error Current->rp=0 detected in aclear() in file amigamesa.c\n");
  240.         }
  241.     
  242. }
  243.  
  244.  
  245. static void aset_index( GLuint index )
  246. {
  247.    /* Set the current color index. */
  248. /*printf("aset_index(%d)\n",index);*/
  249.     Current->pixel = Current->penconv[index];
  250. }
  251.  
  252.  
  253.  
  254. static void aset_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  255. {
  256. /*printf("aset_color(%d,%d,%d,%d)\n",r,g,b,a);*/
  257.  
  258.         /* Set the current RGBA color. */
  259.         /* r is in 0..CC.RedScale */
  260.         /* g is in 0..CC.GreenScale */
  261.         /* b is in 0..CC.BlueScale */
  262.         /* a is in 0..CC.AlphaScale */
  263.     Current->pixel = RGBA(r,g,b,a);
  264.     /*(a << 24) | (r << 16) | (g << 8) | b;*/
  265. }
  266.  
  267.  
  268.  
  269. static GLboolean aindex_mask( GLuint mask )
  270. {
  271.    /* implement glIndexMask if possible, else return GL_FALSE */
  272. /*printf("aindex_mask(0x%x)\n",mask);*/
  273.     Current->rp->Mask = (UBYTE) mask;
  274.  
  275.     return(GL_TRUE);
  276. }
  277.  
  278.  
  279.  
  280. static GLboolean acolor_mask( GLboolean rmask, GLboolean gmask,
  281.                              GLboolean bmask, GLboolean amask)
  282. {
  283.    /* implement glColorMask if possible, else return GL_FALSE */
  284.     return(GL_FALSE);
  285.     
  286. }
  287.  
  288.  
  289.  
  290. static GLboolean alogicop( GLenum op )
  291. {
  292.    /*
  293.     * Implements glLogicOp if possible.  Return GL_TRUE if the device driver
  294.     * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  295.     * is returned, the logic op will be done in software by Mesa.
  296.     */
  297.     return(GL_FALSE);
  298. }
  299.  
  300.  
  301. static void adither( GLboolean enable )
  302. {
  303.    /* enable/disable dithering if applicable */
  304. }
  305.  
  306.  
  307.  
  308. static GLboolean aset_buffer( GLenum mode )
  309. {
  310.    /* set the current drawing/reading buffer, return GL_TRUE or GL_FALSE */
  311.    /* for success/failure */
  312.     
  313. /*    amiga_setup_DD_pointers(); in ddsample is this right?????*/
  314. /*    printf("aset_buffer TODO\n");*/
  315.     
  316.  
  317. /* TODO implemed a set of buffers */
  318.     if (mode==GL_FRONT)
  319.         {
  320.         return(GL_TRUE);
  321.         }
  322.     else if (mode==GL_BACK)
  323.         {
  324.         return(GL_TRUE);
  325.         }
  326.     else
  327.         {
  328.         return(GL_FALSE);
  329.         }
  330. }
  331.  
  332.  
  333.  
  334. static void abuffer_size( GLuint *width, GLuint *height, GLuint *depth )
  335. {
  336.    /* return the width, height and depth (bits/pixel) of the current buffer */
  337.    /* if anything special has to been done when the buffer/window is        */
  338.    /* resized, do it now                                                    */
  339. /*    printf("abuffer_size\n");*/
  340.  
  341.  
  342.     if(!((*width=Current->width) ==(Current->window->Width - Current->window->BorderLeft - Current->window->BorderRight)&&
  343.      ((*height=Current->height) ==(Current->window->Height - Current->window->BorderTop - Current->window->BorderBottom))))
  344.         {
  345.         FreeOneLine(Current);
  346.         Current->width =Current->window->Width - Current->window->BorderLeft - Current->window->BorderRight;
  347.         Current->height=Current->window->Height - Current->window->BorderTop - Current->window->BorderBottom;
  348.         Current->left = Current->window->BorderLeft;
  349.         Current->bottom = Current->window->Height - Current->window->BorderBottom - 1;
  350.  
  351.         destroy_temp_raster( Current->rp); /* deallocate temp raster */
  352.  
  353.  
  354.         if (Current->db_flag)
  355.             {
  356.             if (Current->back_rp)                            /* Fix dubbel buffer */
  357.                 {
  358.                 destroy_rastport(Current->back_rp);
  359.                 }
  360.             if((Current->back_rp = make_rastport(Current->window->Width,Current->window->Height,Current->depth))==NULL)
  361.                 {
  362.                 Current->rp = Current->front_rp;
  363.                 printf("To little mem free. Couldn't allocate Dubblebuffer in this size.\n");
  364.                 }
  365.             else
  366.                 {
  367.                 Current->rp=Current->back_rp;
  368.                 }
  369.             }
  370.             
  371.         if (Current->rgb_flag)
  372.             {
  373.           /* RGBA color buffers */
  374.             Current->gl_ctx->RGBAflag = GL_TRUE;
  375.             *depth= 24; /* TODO */
  376.             Current->depth =Current->depth = Current->window->RPort->BitMap->Depth;
  377.             }
  378.         else
  379.            {
  380.           /* CI color buffers */
  381.             Current->gl_ctx->RGBAflag = GL_FALSE;
  382.             *depth=Current->depth = Current->window->RPort->BitMap->Depth;
  383.  
  384.             }
  385.  
  386.         if(!make_temp_raster( Current->rp ))
  387.             printf("Error allocating TmpRasterPort\n");
  388.     
  389.         AllocOneLine(Current);
  390.     }
  391.  
  392. }    
  393.  
  394.  
  395. /**********************************************************************/
  396. /*****           Accelerated point, line, polygon rendering       *****/
  397. /**********************************************************************/
  398.  
  399.  
  400. static void afast_points_function( GLuint first, GLuint last )
  401. {
  402.  
  403.    /* Render a number of points by some hardware/OS accerated method */
  404.  
  405.     int i,col;
  406. /* printf("afast_points_function\n");*/
  407.     
  408.  
  409.    if (VB.MonoColor) {
  410.       /* draw all points using the current color (set_color) */
  411.             SetAPen(Current->rp,Current->pixel);
  412. /*            printf("VB.MonoColor\n");*/
  413.       for (i=first;i<=last;i++) {
  414.          if (VB.Unclipped[i]) {
  415.             /* compute window coordinate */
  416.             int x, y;
  417.             x =FIXx((GLint) (VB.Win[i][0]));
  418.             y =FIXy((GLint) (VB.Win[i][1]));
  419.                         WritePixel(Current->rp,x,y);
  420. /*                        printf("WritePixel(%d,%d)\n",x,y);*/
  421.          }
  422.       }
  423.    }
  424.    else {
  425.       /* each point is a different color */
  426. /*            printf("!VB.MonoColor\n");*/
  427.  
  428.       for (i=first;i<=last;i++) {
  429.          /*if (VB.Unclipped[i])*/ {
  430.             int x, y;
  431.             x =FIXx((GLint) (VB.Win[i][0]));
  432.               y =FIXy((GLint) (VB.Win[i][1])); 
  433.               col=*VB.Color[i];
  434.               SetAPen(Current->rp,Current->penconv[col]);
  435.                         WritePixel(Current->rp,x,y);
  436. /*                        printf("WritePixel(%d,%d)\n",x,y);*/
  437.          }
  438.       }
  439.    }
  440. }
  441.  
  442.  
  443.  
  444. static points_func achoose_points_function( void )
  445. {
  446. /*printf("achoose_points_function\n");*/
  447.    /* Examine the current rendering state and return a pointer to a */
  448.    /* fast point-rendering function if possible. */
  449.    if (CC.Point.Size==1.0 && !CC.Point.SmoothFlag && CC.RasterMask==0
  450.        && !CC.Texture.Enabled /*&&  ETC, ETC */) {
  451.       return afast_points_function;
  452.    }
  453.    else {
  454.       return afast_points_function;
  455. /*      return NULL;*/
  456.    }
  457. }
  458.  
  459.  
  460.  
  461. static void afast_line_function( GLuint v0, GLuint v1, GLuint pv )
  462. {
  463.  
  464.                                            /* Render a line by some hardware/OS accerated method */
  465.     int x0, y0, x1, y1;
  466. /*    printf("afast_line_function\n");*/
  467.  
  468.     if (VB.MonoColor)
  469.         {
  470.         SetAPen(Current->rp,Current->pixel);
  471.         }
  472.     else
  473.         {
  474.         SetAPen(Current->rp,Current->penconv[*VB.Color[pv]]);
  475.         }
  476.     x0 = FIXx((int) (VB.Win[v0][0]));
  477.     y0 = FIXy((int) (VB.Win[v0][1]));
  478.     x1 = FIXx((int) (VB.Win[v1][0]));
  479.     y1 = FIXy((int) (VB.Win[v1][1]));
  480.  
  481.     Move(Current->rp,x0,y0);
  482.     Draw(Current->rp,x1,y1);
  483. }
  484.  
  485.  
  486.  
  487. static line_func achoose_line_function( void )
  488. {
  489.     /*printf("achoose_line_function\n");*/
  490.  
  491.    /* Examine the current rendering state and return a pointer to a */
  492.    /* fast line-rendering function if possible. */
  493.  
  494.    if (CC.Line.Width==1.0 && !CC.Line.SmoothFlag && !CC.Line.StippleFlag
  495.        && CC.Light.ShadeModel==GL_FLAT && CC.RasterMask==0
  496.        && !CC.Texture.Enabled /*&&  ETC, ETC */ ) 
  497.         {
  498.         return afast_line_function;
  499.         }
  500.     else 
  501.         {
  502.  
  503.         return NULL;
  504.         }
  505. }
  506.  
  507. /*
  508.  * Draw a filled polygon of a single color.  If there is hardware/OS support
  509.  * for polygon drawing use that here.  Otherwise, call a function in
  510.  * polygon.c to do the drawing.
  511.  */
  512.  
  513. static void afast_polygon_function( GLuint n, GLuint vlist[], GLuint pv )
  514. {
  515.     int i,j;
  516.  
  517.    /* Render a line by some hardware/OS accerated method */
  518. /*    printf("afast_polygon_function\n");*/
  519.  
  520.     if (VB.MonoColor)
  521.         {
  522.         SetAPen(Current->rp,Current->pixel);
  523.         }
  524.     else
  525.         {
  526.         SetAPen(Current->rp,Current->penconv[*VB.Color[pv]]);
  527.         }
  528.  
  529.  
  530.     AreaMove(Current->rp, FIXx((int) VB.Win[0][0]), FIXy( (int) VB.Win[0][1]));
  531.  
  532.  
  533.     for (i=1;i<n;i++)
  534.         {
  535.         j=vlist[i];
  536.         AreaDraw( Current->rp, FIXx((int) VB.Win[j][0]), FIXy( (int) VB.Win[j][1]));
  537.  
  538.         }
  539.     AreaEnd( Current->rp );
  540.  
  541. }
  542.  
  543.  
  544.  
  545. static polygon_func achoose_polygon_function( void )
  546. {
  547.     /*    printf("achoose_polygon_function\n");*/
  548.  
  549.    /* Examine the current rendering state and return a pointer to a */
  550.    /* fast polygon-rendering function if possible. */
  551.     if (!CC.Polygon.SmoothFlag && !CC.Polygon.StippleFlag
  552.        && CC.Light.ShadeModel==GL_FLAT && CC.RasterMask==0
  553.        && !CC.Texture.Enabled /*&&  ETC, ETC */ )
  554.         {
  555.     return afast_polygon_function; 
  556. /*        return NULL;*/
  557.         }
  558.     else 
  559.         {
  560.         return NULL;
  561.         }
  562. }
  563.  
  564.  
  565.  
  566. /**********************************************************************/
  567. /*****            Write spans of pixels                           *****/
  568. /**********************************************************************/
  569.  
  570.  
  571. static void awrite_index_span( GLuint n, GLint x, GLint y,
  572.                               const GLuint index[],
  573.                               const GLubyte mask[] )
  574. {
  575.    int     i,ant;
  576.    UBYTE *dp;
  577.  /*    printf("awrite_index_span(%d,%d,%d)\n",n,x,y);getchar();    */
  578.  
  579.     y=FIXy(y);
  580.     x=FIXx(x);
  581.     if((dp = Current->imageline) && Current->tmpras)
  582.         {                /* if imageline allocated then use fastversion */
  583.  
  584.         ant=0;
  585.        for (i=0;i<n;i++)                 /* draw pixel (x[i],y[i]) using index[i] */
  586.            {
  587.           if (mask[i])
  588.               {
  589.               ant++;
  590.               x++;
  591.                 *dp++ = Current->penconv[index[i]];
  592.                 }
  593.             else
  594.                 {
  595.                 if(ant)
  596.                     WritePixelLine8(Current->rp,x,y,ant,Current->imageline,Current->tmpras);
  597.                 dp=Current->imageline;                 
  598.                 ant=0;
  599.                 x++;
  600.                 }
  601.             }
  602.         if(ant)
  603.             WritePixelLine8(Current->rp,x,y,ant,Current->imageline,Current->tmpras);
  604.  
  605.         }
  606.     else
  607.         {          /* Slower */
  608.        for (i=0;i<n;i++,x++)
  609.            {
  610.           if (mask[i])
  611.               {
  612.              /* draw pixel (x[i],y[i]) using index[i] */
  613.                 SetAPen(Current->rp,Current->penconv[index[i]]);
  614.                 WritePixel(Current->rp,x,y);
  615.                 }
  616.  
  617.             }
  618.         
  619.         }
  620. }
  621.  
  622.  
  623.  
  624. static void awrite_monoindex_span(GLuint n,GLint x,GLint y,const GLubyte mask[])
  625. {
  626.    int i;
  627. /*    printf("awrite_monoindex_span(%d,%d,%d)<\n",n,x,y);getchar();    */
  628.     
  629.  
  630.     SetAPen(Current->rp,Current->pixel);
  631.     y=FIXy(y);
  632.     x=FIXx(x);
  633.  
  634.     for (i=0;i<n;i++,x++)
  635.     {
  636.     if (mask[i])
  637.         {
  638.          /* draw pixel (x[i],y[i]) using current color index */
  639.         WritePixel(Current->rp,x,y);
  640.     }
  641.     }
  642. }
  643.  
  644.  
  645.  
  646. static void awrite_color_span( GLuint n, GLint x, GLint y,
  647.                               const GLubyte red[], const GLubyte green[],
  648.                               const GLubyte blue[], const GLubyte alpha[],
  649.                               const GLubyte mask[] )
  650. {
  651.    int i;
  652. /*    printf("awrite_color_span(%d,%d,%d)<\n",n,x,y);    getchar();    */
  653.     
  654.  
  655.     y=FIXy(y);
  656.     x=FIXx(x);
  657.     if (mask)
  658.         {
  659.       /* draw some pixels */
  660.         for (i=0; i<n; i++, x++)
  661.             {
  662.             if (mask[i])
  663.                 {
  664.             /* draw pixel x,y using color red[i]/green[i]/blue[i]/alpha[i] */
  665.                 SetAPen(Current->rp,RGBA(red[i],green[i],blue[i],alpha[i]));
  666.                 WritePixel(Current->rp,x,y);
  667.                 }
  668.             }
  669.         }
  670.     else
  671.         {
  672.       /* draw all pixels */
  673.         for (i=0; i<n; i++, x++)
  674.             {
  675.          /* draw pixel x,y using color red[i]/green[i]/blue[i]/alpha[i] */
  676.             SetAPen(Current->rp,RGBA(red[i],green[i],blue[i],alpha[i]));
  677.             WritePixel(Current->rp,x,y);
  678.             }
  679.         }
  680. }
  681.  
  682.  
  683.  
  684. static void awrite_monocolor_span( GLuint n, GLint x, GLint y,
  685.                                   const GLubyte mask[])
  686. {
  687.    int i;
  688.     /*printf("awrite_monocolor_span(%d,%d,%d)<<<<<<<\n",n,x,y);    getchar();    */
  689.     
  690.  
  691.     y=FIXy(y);
  692.     x=FIXx(x);
  693.     SetAPen(Current->rp,Current->pixel);
  694.  
  695.    for (i=0; i<n; i++, x++) {
  696.       if (mask[i]) {
  697.                     WritePixel(Current->rp,x,y);
  698.       }
  699.    }
  700. }
  701.  
  702.  
  703.  
  704. /**********************************************************************/
  705. /*****                 Read spans of pixels                       *****/
  706. /**********************************************************************/
  707.  
  708.  
  709. static void aread_index_span( GLuint n, GLint x, GLint y, GLuint index[])
  710. {
  711.    int i;
  712.      /*printf("aread_index_span>>\n");*/
  713.     
  714.  
  715.      y=FIXy(y);
  716.     x=FIXx(x);
  717.     for (i=0; i<n; i++,x++)
  718.         {
  719.         index[i] = ReadPixel(Current->rp,x,y);
  720.         }
  721. }
  722.  
  723.  
  724.  
  725. static void aread_color_span( GLuint n, GLint x, GLint y,
  726.                              GLubyte red[], GLubyte green[],
  727.                              GLubyte blue[], GLubyte alpha[] )
  728. {
  729.     int i,col;
  730.     ULONG ColTab[3];
  731.  
  732.      /*printf("aread_color_span>>\n");*/
  733.          
  734.  
  735.      y=FIXy(y);
  736.     x=FIXx(x);
  737.     for (i=0; i<n; i++, x++)
  738.         {
  739.         col=ReadPixel(Current->rp,x,y);
  740.         GetRGB32(Current->window->WScreen->ViewPort.ColorMap,col,1,ColTab);
  741.  
  742.         red[i]   = ColTab[0]>>24;
  743.         green[i] = ColTab[1]>>24;
  744.         blue[i]  = ColTab[2]>>24;
  745.         alpha[i]=255;
  746.  
  747.    }
  748. }
  749.  
  750.  
  751.  
  752. /**********************************************************************/
  753. /*****              Write arrays of pixels                        *****/
  754. /**********************************************************************/
  755.  
  756.  
  757. static void awrite_index_pixels( GLuint n, const GLint x[], const GLint y[],
  758.                                 const GLuint index[], const GLubyte mask[] )
  759. {
  760.    int i;
  761.      /*printf("awrite_index_pixels<\n");*/
  762.     
  763.  
  764.    for (i=0; i<n; i++) {
  765.       if (mask[i]) {
  766. /*         plot pixel x[i], y[i] using index[i] */
  767.         SetAPen(Current->rp,Current->penconv[index[i]]);
  768.         WritePixel(Current->rp,FIXx(x[i]),FIXy(y[i]));
  769.  
  770.       }
  771.    }
  772. }
  773.  
  774.  
  775.  
  776. static void awrite_monoindex_pixels( GLuint n,
  777.                                     const GLint x[], const GLint y[],
  778.                                     const GLubyte mask[] )
  779. {
  780.    int i;
  781.      /*printf("awrite_monoindex_pixels<\n");*/
  782.          
  783.  
  784.         SetAPen(Current->rp,Current->pixel);
  785.  
  786.    for (i=0; i<n; i++) {
  787.       if (mask[i]) {
  788. /*         write pixel x[i], y[i] using current index  */
  789.         WritePixel(Current->rp,FIXx(x[i]),FIXy(y[i]));
  790.  
  791.       }
  792.    }
  793. }
  794.  
  795.  
  796.  
  797. static void awrite_color_pixels( GLuint n, const GLint x[], const GLint y[],
  798.                                 const GLubyte r[], const GLubyte g[],
  799.                                 const GLubyte b[], const GLubyte a[],
  800.                                 const GLubyte mask[] )
  801. {
  802.    int i;
  803. /*     printf("awrite_color_pixels<\n");*/
  804.     
  805.  
  806.    for (i=0; i<n; i++) {
  807.       if (mask[i]) {
  808. /*         write pixel x[i], y[i] using red[i],green[i],blue[i],alpha[i] */
  809.         SetAPen(Current->rp,RGBA(r[i],g[i],b[i],a[i]));
  810.         WritePixel(Current->rp,FIXx(x[i]),FIXy(y[i]));
  811.       }
  812.    }
  813. }
  814.  
  815.  
  816.  
  817. static void awrite_monocolor_pixels( GLuint n,
  818.                                     const GLint x[], const GLint y[],
  819.                                     const GLubyte mask[] )
  820. {
  821.    int i;
  822. /*     printf("awrite_monocolor_pixels<\n");*/
  823.          
  824.  
  825.         SetAPen(Current->rp,Current->pixel);
  826.  
  827.    for (i=0; i<n; i++) {
  828.       if (mask[i]) {
  829. /*         write pixel x[i], y[i] using current color*/
  830.         WritePixel(Current->rp,FIXx(x[i]),FIXy(y[i]));
  831.       }
  832.    }
  833. }
  834.  
  835.  
  836.  
  837.  
  838. /**********************************************************************/
  839. /*****                   Read arrays of pixels                    *****/
  840. /**********************************************************************/
  841.  
  842. /* Read an array of color index pixels. */
  843. static void aread_index_pixels( GLuint n, const GLint x[], const GLint y[],
  844.                                GLuint index[], const GLubyte mask[] )
  845. {
  846.   int i;
  847. /*    printf("aread_index_pixels-\n");*/
  848.     
  849.  
  850.   for (i=0; i<n; i++) {
  851.      if (mask[i]) {
  852. /*        index[i] = read_pixel x[i], y[i] */
  853.         index[i] = ReadPixel(Current->rp,FIXx(x[i]),FIXy(y[i]));
  854.      }
  855.   }
  856. }
  857.  
  858.  
  859.  
  860. static void aread_color_pixels( GLuint n, const GLint x[], const GLint y[],
  861.                                GLubyte red[], GLubyte green[],
  862.                                GLubyte blue[], GLubyte alpha[],
  863.                                const GLubyte mask[] )
  864. {
  865.     int i,col;
  866.     ULONG ColTab[3];
  867.  
  868. /*    printf("aread_color_pixels-\n");*/
  869.         
  870.  
  871.     for (i=0; i<n; i++)
  872.         {
  873.         if (mask[i])
  874.             {
  875.             col=ReadPixel(Current->rp,FIXx(x[i]),FIXy(y[i]));
  876.  
  877.             GetRGB32(Current->window->WScreen->ViewPort.ColorMap,col,1,ColTab);
  878.  
  879.             red[i]   = ColTab[0]>>24;
  880.             green[i] = ColTab[1]>>24;
  881.             blue[i]  = ColTab[2]>>24;
  882.             alpha[i]=255;
  883.       }
  884.    }
  885. }
  886.  
  887.  
  888.  
  889.  
  890. /**********************************************************************/
  891. /**********************************************************************/
  892.  
  893.  
  894. /* org:static void setup_DD_pointers( void ) */
  895.  
  896. void amiga_setup_DD_pointers( void )
  897. {
  898.    /* Initialize all the pointers in the DD struct.  Do this whenever */
  899.    /* a new context is made current or we change buffers via set_buffer! */
  900.  
  901.    DD.finish = afinish;
  902.    DD.flush = aflush;
  903.  
  904.    DD.clear_index = aclear_index;
  905.    DD.clear_color = aclear_color;
  906.    DD.clear = aclear;
  907.  
  908.    DD.index = aset_index;
  909.    DD.color = aset_color;
  910.    DD.index_mask = aindex_mask;
  911.    DD.color_mask = acolor_mask;
  912.  
  913.    DD.logicop = alogicop;
  914.    DD.dither = adither;
  915.  
  916.    DD.set_buffer = aset_buffer;
  917.    DD.buffer_size = abuffer_size;
  918.  
  919.    DD.get_points_func = achoose_points_function;
  920.    DD.get_line_func = achoose_line_function;
  921.    DD.get_polygon_func = achoose_polygon_function;
  922.  
  923.    /* Pixel/span writing functions: */
  924.    DD.write_color_span       = awrite_color_span;
  925.    DD.write_monocolor_span   = awrite_monocolor_span;
  926.    DD.write_color_pixels     = awrite_color_pixels;
  927.    DD.write_monocolor_pixels = awrite_monocolor_pixels;
  928.    DD.write_index_span       = awrite_index_span;
  929.    DD.write_monoindex_span   = awrite_monoindex_span;
  930.    DD.write_index_pixels     = awrite_index_pixels;
  931.    DD.write_monoindex_pixels = awrite_monoindex_pixels;
  932.  
  933.    /* Pixel/span reading functions: */
  934.    DD.read_index_span = aread_index_span;
  935.    DD.read_color_span = aread_color_span;
  936.    DD.read_index_pixels = aread_index_pixels;
  937.    DD.read_color_pixels = aread_color_pixels;
  938. }
  939.  
  940.  
  941.  
  942. /**********************************************************************/
  943. /*****               Amiga/Mesa Private Functions                 *****/
  944. /**********************************************************************/
  945.  
  946.  
  947. /*
  948.  * Create a new rastport to use as a back buffer.
  949.  * Input:  width, height - size in pixels
  950.  *         depth - number of bitplanes
  951.  */
  952. struct RastPort *make_rastport( int width, int height, int depth )
  953. {
  954.     struct RastPort *rp;
  955.     struct BitMap *bm;
  956.  
  957.     if (bm=AllocBitMap(width,height,depth,BMF_CLEAR|BMF_INTERLEAVED,0))
  958.         {
  959.         if (rp = (struct RastPort *) malloc( sizeof(struct RastPort)))
  960.             {
  961.             InitRastPort( rp );
  962.             rp->BitMap = bm;
  963.             return rp;
  964.             }
  965.         else
  966.             {
  967.             FreeBitMap(bm);
  968.             return 0;
  969.             }
  970.         }
  971.     else
  972.         return 0;
  973. }
  974.  
  975.  
  976.  
  977. /*
  978.  * Deallocate a rastport.
  979.  */
  980.  
  981. void destroy_rastport( struct RastPort *rp )
  982. {
  983.     WaitBlit();
  984.     FreeBitMap( rp->BitMap );
  985.     free( rp );
  986. }
  987.  
  988.  
  989.  
  990. /*
  991.  * Construct a temporary raster for use by the given rasterport.
  992.  * Temp rasters are used for polygon drawing.
  993.  */
  994.  
  995.  
  996.  
  997. BOOL static make_temp_raster( struct RastPort *rp )
  998. {
  999.     BOOL    OK;
  1000.     unsigned long width, height;
  1001.    PLANEPTR p;
  1002.    struct TmpRas *tmpras;
  1003.  
  1004.     OK=TRUE;
  1005.     if(rp==0)
  1006.         {
  1007.         printf("Zero rp\n");
  1008.         return(FALSE);
  1009.         }
  1010.    width = rp->BitMap->BytesPerRow*8;
  1011.    height = rp->BitMap->Rows;
  1012.  
  1013.     /* allocate structures */
  1014.    p = AllocRaster( width, height );
  1015.     if(p!=0)
  1016.         {
  1017.        tmpras = (struct TmpRas *) AllocVec( sizeof(struct TmpRas),MEMF_ANY);
  1018.         if(tmpras!=0)
  1019.             {
  1020.               if(InitTmpRas( tmpras, p, ((width+15)/16)*height ))
  1021.                 {
  1022. /*                Current->tmpras=tmpras;*/
  1023.                 rp->TmpRas = tmpras;
  1024.                 }
  1025.            else
  1026.                OK=FALSE;
  1027.            }
  1028.         else
  1029.             OK=FALSE;
  1030.         }
  1031.     else
  1032.         return(FALSE);
  1033.     
  1034.     if (OK)
  1035.         return(TRUE);
  1036.     else
  1037.         {
  1038.         printf("Error when allocationg TmpRas\n");
  1039.         if (tmpras)
  1040.             FreeVec(tmpras);
  1041.         if (p)
  1042.             FreeRaster(p,width, height);
  1043.         return(FALSE);
  1044.        }
  1045.  
  1046.  
  1047. }
  1048.  
  1049. BOOL allocarea(struct RastPort *rp )
  1050.     {
  1051.     BOOL    OK;
  1052.     struct AreaInfo *areainfo;
  1053.    UWORD *pattern;
  1054.    APTR vbuffer;
  1055.  
  1056.     OK=TRUE;
  1057.    
  1058.       areainfo = (struct AreaInfo *) AllocVec( sizeof(struct AreaInfo),MEMF_ANY );
  1059.     if(areainfo!=0)
  1060.         {
  1061.         pattern = (UWORD *) AllocVec( sizeof(UWORD),MEMF_ANY);
  1062.         if(pattern!=0)
  1063.             {
  1064.              *pattern = 0xffff;        /*@@@ org: 0xffffffff*/
  1065.             vbuffer = (APTR) AllocVec( MAX_POLYGON * 5 * sizeof(WORD),MEMF_ANY);
  1066.             if(vbuffer!=0)
  1067.                {
  1068.                 /* initialize */
  1069.                 InitArea( areainfo, vbuffer, MAX_POLYGON );
  1070.                   /* bind to rastport */
  1071.                   rp->AreaPtrn = pattern;
  1072.                   rp->AreaInfo = areainfo;
  1073.                   rp->AreaPtSz = 0;
  1074.                  }
  1075.              else
  1076.                     OK=FALSE;
  1077.                 }
  1078.        else
  1079.              OK=FALSE;
  1080.        }
  1081.    else    
  1082.              OK=FALSE;   
  1083.     /*    return(FALSE);*/
  1084.         
  1085.     if (OK)
  1086.         return (OK);
  1087.     else
  1088.         {
  1089.         printf("Error when allocationg AreaBuffers\n");
  1090.         if (vbuffer)
  1091.             FreeVec(vbuffer);
  1092.         if (pattern)
  1093.             FreeVec(pattern);
  1094.         if (areainfo)
  1095.             FreeVec(areainfo);
  1096.         return(OK);
  1097.        }
  1098.             
  1099.     }
  1100.  
  1101. void freearea(struct RastPort *rp)
  1102.     {
  1103.     if (rp->AreaInfo)
  1104.         {
  1105.         if (rp->AreaInfo->VctrTbl)
  1106.             FreeVec(rp->AreaInfo->VctrTbl);
  1107.         if (rp->AreaPtrn)
  1108.             {
  1109.             FreeVec(rp->AreaPtrn);
  1110.             rp->AreaPtrn=NULL;
  1111.             }
  1112.         FreeVec(rp->AreaInfo);
  1113.         rp->AreaInfo=NULL;
  1114.         }
  1115.     }
  1116. /*
  1117.  * Destroy a temp raster.
  1118.  */
  1119.  
  1120. static void destroy_temp_raster( struct RastPort *rp )
  1121. {
  1122.    /* bitmap */
  1123.     
  1124.     unsigned long width, height;
  1125.     
  1126.    width = rp->BitMap->BytesPerRow*8;
  1127.    height = rp->BitMap->Rows;
  1128.  
  1129.     if (rp->TmpRas)
  1130.         {
  1131.         if(rp->TmpRas->RasPtr)
  1132.             FreeRaster( rp->TmpRas->RasPtr,width,height );
  1133.         FreeVec( rp->TmpRas );
  1134.         rp->TmpRas=NULL;
  1135. /*        Current->tmpras = NULL;*/
  1136.         
  1137.         }
  1138. }
  1139.  
  1140. void AllocOneLine( struct amigamesa_context *c)
  1141.     {
  1142.     if(c->imageline)
  1143.         FreeVec(c->imageline);
  1144.     c->imageline = AllocVec((c->width+15) & 0xfffffff0,MEMF_ANY);  /* One Line */
  1145.     }
  1146.     
  1147. void FreeOneLine( struct amigamesa_context *c)
  1148.     {
  1149.     if(c->imageline)
  1150.         {
  1151.         FreeVec(c->imageline);
  1152.         c->imageline=NULL;
  1153.         }
  1154.         
  1155.     }
  1156.  
  1157. BOOL InitLibrary(void)
  1158.     {
  1159.     if(!GfxBase)
  1160.         {
  1161. /*        printf("Opening graphics.library\n");*/
  1162.         if (!(GfxBase = OpenLibrary("graphics.library",39)))
  1163.             {
  1164.             printf("MesaOpenGL Error\nCouldent open graphics.library v39\n");
  1165.             return(FALSE);
  1166.             }
  1167.         }
  1168. /*    printf("GfxBase=0x%x\n",GfxBase);*/
  1169.     return(TRUE);
  1170.     }
  1171.  
  1172. void DisposeLibrary(void)
  1173.     {
  1174.     if (GfxBase)   /* @@@ TODO Open and close gfxlibrary when open and flush lib.*/
  1175.         CloseLibrary(GfxBase);
  1176.     GfxBase=NULL;
  1177.     }
  1178.  
  1179. /**********************************************************************/
  1180. /*****               Amiga/Mesa API Functions                     *****/
  1181. /**********************************************************************/
  1182.  
  1183.  
  1184. /*
  1185.  * Implement the client-visible Amiga/Mesa interface functions defined
  1186.  * in Mesa/include/GL/Amigamesa.h
  1187.  */
  1188.  
  1189. __asm __saveds struct amigamesa_context *AmigaMesaCreateContext(register __a1 struct Window *window,register __d0 GLboolean rgb_flag,register __d1 GLboolean db_flag )
  1190. {
  1191.    /* Create a new Amiga/Mesa context */
  1192.    /* Be sure to initialize the following in the core Mesa context: */
  1193.    /* RedScale, GreenScale, BlueScale, AlphaScale */
  1194.    /* DrawBuffer, ReadBuffer */  /* @@@ IMPLEMENTERA ???*/
  1195.    /* RGBAflag, DBflag */
  1196.    
  1197.     GLfloat redscale,greenscale,bluescale,alphascale;
  1198.     int            I;
  1199.     struct amigamesa_context *c;
  1200.  
  1201. /*    printf("Hello and welcome to a Libfunction\n");*/
  1202.  
  1203.       /* allocate amigamesa_context struct initialized to zeros */
  1204.     c = (struct amigamesa_context *) AllocVec(sizeof(struct amigamesa_context),MEMF_PUBLIC|MEMF_CLEAR);
  1205.     if (!c)
  1206.         {
  1207.         printf("Not able to create mesa_context. You are VERY low on memory.\n");
  1208.         return(NULL);
  1209.         }
  1210.     
  1211.  
  1212.     c->sharelist=NULL;                                                             /* shared viewarea */
  1213.     redscale=greenscale=bluescale=alphascale=255.0;
  1214.  
  1215.  
  1216.     c->gl_ctx = gl_new_context( rgb_flag,
  1217.                                redscale, greenscale, bluescale, alphascale,
  1218.                                db_flag, NULL );  /*c->sharelist->gl_ctx ); @@@ tillfälligt */
  1219.     c->rgb_flag = rgb_flag;
  1220.     c->db_flag = db_flag;
  1221.  
  1222.     c->front_rp =window->RPort;
  1223.         c->back_rp=NULL;
  1224.         c->rp = c->front_rp;
  1225.  
  1226.     c->window = window;
  1227.  
  1228.     c->width = window->Width - window->BorderLeft - window->BorderRight;
  1229.     c->height = window->Height - window->BorderTop - window->BorderBottom;
  1230.     c->left = window->BorderLeft;
  1231.     c->bottom = window->Height - window->BorderBottom - 1;
  1232.  
  1233.     c->depth = c->rp->BitMap->Depth;
  1234.  
  1235.     c->gl_ctx->BufferWidth = c->width;
  1236.     c->gl_ctx->BufferHeight = c->height;
  1237.         
  1238.     if (rgb_flag)
  1239.         {
  1240.       /* RGBA color buffers */
  1241.         c->gl_ctx->RGBAflag = GL_TRUE;
  1242.         c->pixel = 0;
  1243.         }
  1244.     else
  1245.        {
  1246.       /* CI color buffers */
  1247.         c->gl_ctx->RGBAflag = GL_FALSE;
  1248.         c->pixel = 0;
  1249.         }
  1250.  
  1251.     if (db_flag)
  1252.         {
  1253.         if((c->back_rp = make_rastport(c->window->Width,c->window->Height,c->depth))!=NULL)
  1254.             {
  1255.     /*        printf("make_rastport OK\n");*/
  1256.             c->gl_ctx->Color.DrawBuffer = GL_BACK;
  1257.             c->rp = c->back_rp;
  1258.             }
  1259.         else
  1260.             {
  1261.             printf("make_rastport Faild\n");
  1262.             c->gl_ctx->Color.DrawBuffer = GL_FRONT;
  1263.             }
  1264.         }
  1265.     else
  1266.         {
  1267.         c->gl_ctx->Color.DrawBuffer = GL_FRONT;
  1268.         }
  1269.  
  1270.     
  1271.     AllocOneLine(c); /* A linebuffer for WritePixelLine */
  1272.  
  1273.  
  1274.     if (!make_temp_raster( c->rp ))
  1275.         printf("Error allocating TmpRastPort\n");
  1276.  
  1277.     allocarea(c->rp);
  1278.         
  1279. /*
  1280.    printf("win width = %d\n", (int) window->Width );
  1281.    printf("win height = %d\n", (int) window->Height );
  1282.    printf("left = %d\n", (int) window->BorderLeft );
  1283.    printf("rightt = %d\n", (int) window->BorderRight );
  1284.    printf("top = %d\n", (int) window->BorderTop );
  1285.    printf("bottom = %d\n", (int) c->bottom );
  1286. */
  1287.     for(I=0;I<=255;I++)
  1288.         {
  1289.         c->penconv[I]=I;    /* Fill it with ordenery pen nr */
  1290.         }
  1291. /*   printf("Createcontext finishied\n");*/
  1292.     return c;
  1293. }
  1294.  
  1295.  
  1296. __asm __saveds void AmigaMesaDestroyContext(register __a0 struct amigamesa_context *c )
  1297. {
  1298.    /* destroy a Amiga/Mesa context */
  1299.  
  1300.     int    I;
  1301.  
  1302.     if (c==Current)
  1303.         Current=NULL;
  1304.  
  1305.     FreeOneLine(c);
  1306.     freearea(c->rp);
  1307.  
  1308.     destroy_temp_raster( c->rp);
  1309.  
  1310.     gl_destroy_context( c->gl_ctx );
  1311.  
  1312.  
  1313.     if (c->rgb_flag)
  1314.         {
  1315.         if (c->rgb_buffer)
  1316.             {
  1317.             printf("free(c->rgb_buffer)\n");
  1318.             free( c->rgb_buffer );
  1319.             }
  1320.         }
  1321.  
  1322.     if (c->back_rp)
  1323.         {
  1324.         destroy_rastport( c->back_rp );
  1325.         c->back_rp=NULL;
  1326.         }
  1327.  
  1328.     for(I=0;I<=255;I++)
  1329.         {
  1330. /*        printf("%d=%d\n",I,c->mypen[I]);*/
  1331.         
  1332.         while (c->mypen[I]!=0)            /* TODO This may free some others pen also */
  1333.             {
  1334.             c->mypen[I]-=1;
  1335.             ReleasePen(c->window->WScreen->ViewPort.ColorMap,I);
  1336.             }
  1337.         }
  1338.     FreeVec( c );
  1339. }
  1340.  
  1341.  
  1342. __asm __saveds void AmigaMesaMakeCurrent(register __a0 struct amigamesa_context *c )
  1343. {
  1344.    /* Make the specified context the current one */
  1345.    /* the order of operations here is very important! */
  1346.    gl_set_context( c->gl_ctx );
  1347.    Current = c;
  1348.  
  1349.    amiga_setup_DD_pointers();
  1350.  
  1351.    if (Current->gl_ctx->Viewport.Width==0) {
  1352.       /* initialize viewport to window size */
  1353.       gl_viewport( 0, 0, Current->width, Current->height );
  1354.    }
  1355. }
  1356.  
  1357.  
  1358. __asm __saveds void AmigaMesaSwapBuffers(void)
  1359.     {
  1360.                                      /* copy/swap back buffer to front if applicable */
  1361.     if (Current->back_rp)
  1362.         {
  1363.         UBYTE minterm = 0xc0;
  1364.         int x = Current->window->BorderLeft;
  1365.         int y = Current->window->BorderTop;
  1366.         
  1367.  
  1368.         ClipBlit( Current->back_rp, x, y,   /* from */
  1369.                             Current->front_rp, x, y,  /* to */
  1370.                             Current->width, Current->height,  /* size */
  1371.                             minterm );
  1372.         }
  1373.  
  1374.     }
  1375.