home *** CD-ROM | disk | FTP | other *** search
/ MegaDoom Adventures / PMWMEGADOOM.iso / doom / creators / deu52gcc / src / gfx.c < prev    next >
C/C++ Source or Header  |  1994-05-17  |  16KB  |  658 lines

  1. /*
  2.    Doom Editor Utility, by Brendon Wyber and Raphaël Quinet.
  3.  
  4.    You are allowed to use any parts of this code in another program, as
  5.    long as you give credits to the authors in the documentation and in
  6.    the program itself.  Read the file README.1ST for more information.
  7.  
  8.    This program comes with absolutely no warranty.
  9.  
  10.    GFX.C - Graphics routines.
  11. */
  12.  
  13. /* the includes */
  14. #include "deu.h"
  15. #include <math.h>
  16. #include <dos.h>
  17.  
  18. /* if your graphics driver doesn't like circles, draw squares instead */
  19. #ifdef NO_CIRCLES
  20. #define circle( x, y, r)    line( x - r, y - r, x - r, y + r); \
  21.                    line( x - r, y + r, x + r, y + r); \
  22.                        line( x + r, y + r, x + r, y - r); \
  23.                    line( x + r, y - r, x - r, y - r)
  24. #endif /* NO_CIRCLES */
  25.  
  26. #define BGI_PATH "."
  27.  
  28. /* the global variables */
  29. BCINT GfxMode = 0;    /* graphics mode number, or 0 for text */
  30.                /* 1 = 320x200, 2 = 640x480, 3 = 800x600, 4 = 1024x768 */
  31.                /* positive = 16 colors, negative = 256 colors */
  32. BCINT OrigX;        /* the X origin */
  33. BCINT OrigY;        /* the Y origin */
  34. float Scale;        /* the scale value */
  35. BCINT PointerX;        /* X position of pointer */
  36. BCINT PointerY;        /* Y position of pointer */
  37. BCINT ScrMaxX;        /* maximum X screen coord */
  38. BCINT ScrMaxY;        /* maximum Y screen coord */
  39. BCINT ScrCenterX;    /* X coord of screen center */
  40. BCINT ScrCenterY;    /* Y coord of screen center */
  41.  
  42.  
  43. #if defined(__GNUC__)
  44. static int res[5][3] = {{640,480,16},{320,200,256},{640,480,256},
  45.                         {800,600,256},{1024,768,256}};
  46. #endif
  47.  
  48.  
  49. /*
  50.    initialise the graphics display
  51. */
  52.  
  53. void InitGfx()
  54. {
  55.    static Bool firsttime = TRUE;
  56.    static int  gdriver;
  57.    static int  gmode;
  58.    int         errorcode = grNoInitGraph;
  59.  
  60.    printf( "Switching to graphics mode...\n");
  61.  
  62. #if defined(__TURBOC__)
  63.  
  64.    if (firsttime)
  65.    {
  66.       if (VideoMode > 0)
  67.       {
  68.             gdriver = installuserdriver( BGIDriver, NULL);
  69.             gmode = VideoMode;
  70.             initgraph( &gdriver, &gmode, BGI_PATH);
  71.             errorcode = graphresult();
  72.       }
  73.       if (errorcode != grOk)
  74.       {
  75.             gdriver = VGA;
  76.             gmode = VGAHI;
  77.       }
  78.    }
  79.    if (gdriver == VGA || !firsttime)
  80.    {
  81.       initgraph( &gdriver, &gmode, BGI_PATH);
  82.       errorcode = graphresult();
  83.       if (errorcode != grOk)
  84.             ProgError( "graphics error: %s", grapherrormsg( errorcode));
  85.    }
  86.    if (gdriver == VGA)
  87.       GfxMode = 2; /* 640x480x16 */
  88.    else
  89.    {
  90.       GfxMode = -gmode; /* 640x480x256, 800x600x256, or 1024x768x256 */
  91.       SetDoomPalette( 0);
  92.    }
  93.  
  94. #elif defined(__GNUC__)
  95.  
  96.    FakeCursor = FALSE;
  97.  
  98.    if (VideoMode < 0 || VideoMode > 4)
  99.       VideoMode = 0;
  100.    set_BGI_mode_whc( &gdriver, &gmode, res[VideoMode][0], res[VideoMode][1], res[VideoMode][2]);
  101.    initgraph( &gdriver, &gmode, BGI_PATH);
  102.    errorcode = graphresult();
  103.    if(errorcode != grOk)
  104.        ProgError( "graphics error: %s", grapherrormsg( errorcode));
  105.  
  106.  
  107.    if (VideoMode == 0)
  108.       GfxMode = 2; /* 640x480x16 */
  109.    else
  110.    {
  111.       GfxMode = -VideoMode; /* 640x480x256, 800x600x256, or 1024x768x256 */
  112.       SetDoomPalette( 0);
  113.    }
  114. #endif
  115.  
  116.    setlinestyle( 0, 0, 1);
  117.    setbkcolor( TranslateToDoomColor( BLACK));
  118.    settextstyle( 0, 0, 1);
  119.    firsttime = FALSE;
  120.    ScrMaxX = getmaxx();
  121.    ScrMaxY = getmaxy();
  122.    ScrCenterX = ScrMaxX / 2;
  123.    ScrCenterY = ScrMaxY / 2;
  124. }
  125.  
  126.  
  127.  
  128. /*
  129.    terminate the graphics display
  130. */
  131.  
  132. void TermGfx()
  133. {
  134.    if (GfxMode)
  135.    {
  136.       closegraph();
  137.       GfxMode = 0;
  138.    }
  139. }
  140.  
  141.  
  142.  
  143. /*
  144.    switch from VGA 16 colours to VGA 256 colours
  145. */
  146.  
  147. Bool SwitchToVGA256()
  148. {
  149.    static int gdriver = -1;
  150.    int gmode, errorcode;
  151.  
  152. #if defined(__TURBOC__)
  153.  
  154.    if (GfxMode > 0 && gdriver != VGA) /* if 16 colors and not failed before */
  155.    {
  156.       if (gdriver == -1)
  157.       {
  158.            gdriver = installuserdriver( "VGA256", NULL);
  159.         errorcode = graphresult();
  160.       }
  161.       closegraph();
  162.       gmode = 0;
  163.       initgraph( &gdriver, &gmode, BGI_PATH);
  164.       errorcode = graphresult();
  165.       if (errorcode != grOk)
  166.       {
  167.         /* failed for 256 colors - back to 16 colors */
  168.         gdriver = VGA;
  169.         gmode = VGAHI;
  170.         initgraph( &gdriver, &gmode, BGI_PATH);
  171.         errorcode = graphresult();
  172.       }
  173.  
  174. #elif defined(__GNUC__)
  175.  
  176.    if (GfxMode > 0)
  177.    {
  178.       closegraph();
  179.       set_BGI_mode_whc( &gdriver, &gmode, res[1][0], res[1][1], res[1][2]);
  180.       initgraph( &gdriver, &gmode, BGI_PATH);
  181.       errorcode = graphresult();
  182.       if(errorcode != grOk)
  183.       {
  184.          /* failed for 256 colors - back to 16 colors */
  185.          set_BGI_mode_whc( &gdriver, &gmode, res[0][0], res[0][1], res[0][2]);
  186.          initgraph( &gdriver, &gmode, BGI_PATH);
  187.          errorcode = graphresult();
  188.       }
  189.  
  190. #endif
  191.  
  192.       if (errorcode != grOk) /* shouldn't happen */
  193.             ProgError( "graphics error: %s", grapherrormsg( errorcode));
  194.       GfxMode = -1 /* 320x200x256 */;
  195.       SetDoomPalette( 0);
  196.       ScrMaxX = getmaxx();
  197.       ScrMaxY = getmaxy();
  198.       ScrCenterX = ScrMaxX / 2;
  199.       ScrCenterY = ScrMaxY / 2;
  200.       return TRUE;
  201.    }
  202.  
  203.    return FALSE;
  204. }
  205.  
  206.  
  207.  
  208. /*
  209.    switch from VGA 256 colours to VGA 16 colours
  210. */
  211.  
  212. Bool SwitchToVGA16()
  213. {
  214.    if (GfxMode == -1) /* switch only if we are in 320x200x256 colors */
  215.    {
  216. #if defined(__TURBOC__)
  217.       int gdriver, gmode, errorcode;
  218.  
  219.       closegraph();
  220.       gdriver = VGA;
  221.       gmode = VGAHI;
  222.       initgraph( &gdriver, &gmode, BGI_PATH);
  223.       errorcode = graphresult();
  224.       if (errorcode != grOk) /* shouldn't happen */
  225.             ProgError( "graphics error: %s", grapherrormsg( errorcode));
  226.       GfxMode = 2; /* 640x480x16 */
  227.       ScrMaxX = getmaxx();
  228.       ScrMaxY = getmaxy();
  229.       ScrCenterX = ScrMaxX / 2;
  230.       ScrCenterY = ScrMaxY / 2;
  231.  
  232. #elif defined(__GNUC__)
  233.       TermGfx();    /* This is a hack, I just didn't have the time to */
  234.       InitGfx();    /* find out why "the other way" didn't work ... */
  235.       CheckMouseDriver();
  236.       if (UseMouse)
  237.          ShowMousePointer();
  238. #endif
  239.  
  240.       return TRUE;
  241.    }
  242.    return FALSE;
  243. }
  244.  
  245.  
  246.  
  247. /*
  248.    clear the screen
  249. */
  250.  
  251. void ClearScreen()
  252. {
  253.    cleardevice();
  254. }
  255.  
  256.  
  257.  
  258. /*
  259.    set the current drawing color
  260. */
  261.  
  262. void SetColor( BCINT color)
  263. {
  264.    if (GfxMode < 0)
  265.       setcolor( TranslateToDoomColor(color));
  266.    else
  267.       setcolor( color);
  268. }
  269.  
  270.  
  271.  
  272. /*
  273.    draw a line on the screen from map coords
  274. */
  275.  
  276. void DrawMapLine( BCINT mapXstart, BCINT mapYstart, BCINT mapXend, BCINT mapYend)
  277. {
  278.    line( SCREENX( mapXstart), SCREENY( mapYstart), SCREENX( mapXend), SCREENY( mapYend));
  279. }
  280.  
  281.  
  282.  
  283. /*
  284.    draw a circle on the screen from map coords
  285. */
  286.  
  287. void DrawMapCircle( BCINT mapXcenter, BCINT mapYcenter, BCINT mapRadius)
  288. {
  289.    circle( SCREENX( mapXcenter), SCREENY( mapYcenter), (int) (mapRadius * Scale));
  290. }
  291.  
  292.  
  293.  
  294. /*
  295.    draw an arrow on the screen from map coords
  296. */
  297.  
  298. void DrawMapVector( BCINT mapXstart, BCINT mapYstart, BCINT mapXend, BCINT mapYend)
  299. {
  300.    BCINT  scrXstart = SCREENX( mapXstart);
  301.    BCINT  scrYstart = SCREENY( mapYstart);
  302.    BCINT  scrXend   = SCREENX( mapXend);
  303.    BCINT  scrYend   = SCREENY( mapYend);
  304.    double r         = hypot( (double) (scrXstart - scrXend), (double) (scrYstart - scrYend));
  305.    BCINT  scrXoff   = (r >= 1.0) ? (BCINT) ((scrXstart - scrXend) * 8.0 / r * Scale) : 0;
  306.    BCINT  scrYoff   = (r >= 1.0) ? (BCINT) ((scrYstart - scrYend) * 8.0 / r * Scale) : 0;
  307.  
  308.    line( scrXstart, scrYstart, scrXend, scrYend);
  309.    scrXstart = scrXend + 2 * scrXoff;
  310.    scrYstart = scrYend + 2 * scrYoff;
  311.    line( scrXstart - scrYoff, scrYstart + scrXoff, scrXend, scrYend);
  312.    line( scrXstart + scrYoff, scrYstart - scrXoff, scrXend, scrYend);
  313. /*
  314.    line( scrXstart - scrYoff, scrYstart + scrXoff, scrXend + scrXoff, scrYend + scrYoff);
  315.    line( scrXstart + scrYoff, scrYstart - scrXoff, scrXend + scrXoff, scrYend + scrYoff);
  316. */
  317. }
  318.  
  319.  
  320.  
  321. /*
  322.    draw an arrow on the screen from map coords and angle (0 - 65535)
  323. */
  324.  
  325. void DrawMapArrow( BCINT mapXstart, BCINT mapYstart, UBCINT angle)
  326. {
  327.    BCINT  mapXend   = mapXstart + (BCINT) (50 * cos(angle / 10430.37835));
  328.    BCINT  mapYend   = mapYstart + (BCINT) (50 * sin(angle / 10430.37835));
  329.    BCINT  scrXstart = SCREENX( mapXstart);
  330.    BCINT  scrYstart = SCREENY( mapYstart);
  331.    BCINT  scrXend   = SCREENX( mapXend);
  332.    BCINT  scrYend   = SCREENY( mapYend);
  333.    double r         = hypot( scrXstart - scrXend, scrYstart - scrYend);
  334.    BCINT  scrXoff   = (r >= 1.0) ? (BCINT) ((scrXstart - scrXend) * 8.0 / r * Scale) : 0;
  335.    BCINT  scrYoff   = (r >= 1.0) ? (BCINT) ((scrYstart - scrYend) * 8.0 / r * Scale) : 0;
  336.  
  337.    line( scrXstart, scrYstart, scrXend, scrYend);
  338.    scrXstart = scrXend + 2 * scrXoff;
  339.    scrYstart = scrYend + 2 * scrYoff;
  340.    line( scrXstart - scrYoff, scrYstart + scrXoff, scrXend, scrYend);
  341.    line( scrXstart + scrYoff, scrYstart - scrXoff, scrXend, scrYend);
  342. }
  343.  
  344.  
  345.  
  346. /*
  347.    draw a line on the screen from screen coords
  348. */
  349.  
  350. void DrawScreenLine( BCINT Xstart, BCINT Ystart, BCINT Xend, BCINT Yend)
  351. {
  352.    line( Xstart, Ystart, Xend, Yend);
  353. }
  354.  
  355.  
  356.  
  357. /*
  358.    draw a filled in box on the screen from screen coords
  359. */
  360.  
  361. void DrawScreenBox( BCINT Xstart, BCINT Ystart, BCINT Xend, BCINT Yend)
  362. {
  363.    setfillstyle( 1, getcolor());
  364.    bar( Xstart, Ystart, Xend, Yend);
  365. }
  366.  
  367.  
  368.  
  369. /*
  370.    draw a filled-in 3D-box on the screen from screen coords
  371. */
  372.  
  373. void DrawScreenBox3D( BCINT Xstart, BCINT Ystart, BCINT Xend, BCINT Yend)
  374. {
  375.    setfillstyle( 1, TranslateToDoomColor( LIGHTGRAY));
  376.    bar( Xstart + 1, Ystart + 1, Xend - 1, Yend - 1);
  377.    SetColor( DARKGRAY);
  378.    line( Xstart, Yend, Xend, Yend);
  379.    line( Xend, Ystart, Xend, Yend);
  380.    if (Xend - Xstart > 20 && Yend - Ystart > 20)
  381.    {
  382.       line( Xstart + 1, Yend - 1, Xend - 1, Yend - 1);
  383.       line( Xend - 1, Ystart + 1, Xend - 1, Yend - 1);
  384.       SetColor( WHITE);
  385.       line( Xstart + 1, Ystart + 1, Xstart + 1, Yend - 1);
  386.       line( Xstart + 1, Ystart + 1, Xend - 1, Ystart + 1);
  387.    }
  388.    SetColor( WHITE);
  389.    line( Xstart, Ystart, Xend, Ystart);
  390.    line( Xstart, Ystart, Xstart, Yend);
  391.    SetColor( BLACK);
  392. }
  393.  
  394.  
  395.  
  396. /*
  397.    draw a hollow 3D-box on the screen from screen coords
  398. */
  399.  
  400. void DrawScreenBoxHollow( BCINT Xstart, BCINT Ystart, BCINT Xend, BCINT Yend)
  401. {
  402.    setfillstyle( 1, TranslateToDoomColor( BLACK));
  403.    bar( Xstart + 1, Ystart + 1, Xend - 1, Yend - 1);
  404.    SetColor( WHITE);
  405.    line( Xstart, Yend, Xend, Yend);
  406.    line( Xend, Ystart, Xend, Yend);
  407.    if (Xend - Xstart > 20 && Yend - Ystart > 20)
  408.    {
  409.       line( Xstart + 1, Yend - 1, Xend - 1, Yend - 1);
  410.       line( Xend - 1, Ystart + 1, Xend - 1, Yend - 1);
  411.       SetColor( DARKGRAY);
  412.       line( Xstart + 1, Ystart + 1, Xstart + 1, Yend - 1);
  413.       line( Xstart + 1, Ystart + 1, Xend - 1, Ystart + 1);
  414.    }
  415.    SetColor( DARKGRAY);
  416.    line( Xstart, Ystart, Xend, Ystart);
  417.    line( Xstart, Ystart, Xstart, Yend);
  418.    SetColor( WHITE);
  419. }
  420.  
  421.  
  422.  
  423. /*
  424.    draw a meter bar on the screen from screen coords (in a hollow box); max. value = 1.0
  425. */
  426.  
  427. void DrawScreenMeter( BCINT Xstart, BCINT Ystart, BCINT Xend, BCINT Yend, float value)
  428. {
  429.    if (value < 0.0)
  430.       value = 0.0;
  431.    if (value > 1.0)
  432.       value = 1.0;
  433.    setfillstyle( 1, TranslateToDoomColor( BLACK));
  434.    bar( Xstart + 1 + (BCINT) ((Xend - Xstart - 2) * value), Ystart + 1, Xend - 1, Yend - 1);
  435.    setfillstyle( 1, TranslateToDoomColor( LIGHTGREEN));
  436.    bar( Xstart + 1, Ystart + 1, Xstart + 1 + (BCINT) ((Xend - Xstart - 2) * value), Yend - 1);
  437. }
  438.  
  439.  
  440.  
  441. /*
  442.    write text to the screen
  443. */
  444.  
  445. void DrawScreenText( BCINT Xstart, BCINT Ystart, char *msg, ...)
  446. {
  447.    static BCINT lastX;
  448.    static BCINT lastY;
  449.    char temp[ 120];
  450.    va_list args;
  451.  
  452.    va_start( args, msg);
  453.    vsprintf( temp, msg, args);
  454.    va_end( args);
  455.    if (Xstart < 0)
  456.       Xstart = lastX;
  457.    if (Ystart < 0)
  458.       Ystart = lastY;
  459.    outtextxy( Xstart, Ystart, temp);
  460.    lastX = Xstart;
  461.    lastY = Ystart + 10;  /* or textheight("W") ? */
  462. }
  463.  
  464.  
  465.  
  466. /*
  467.    draw (or erase) the pointer if we aren't using the mouse
  468. */
  469.  
  470. void DrawPointer( Bool rulers)
  471. {
  472.    BCINT r;
  473.  
  474.    /* use XOR mode : drawing the pointer twice erases it */
  475.    setwritemode( XOR_PUT);
  476.    /* draw the pointer */
  477.    if ( rulers)
  478.    {
  479.       SetColor( MAGENTA);
  480.       r = (BCINT) (512 * Scale);
  481.       circle( PointerX, PointerY, r);
  482.       r >>= 1;
  483.       circle( PointerX, PointerY, r);
  484.       r >>= 1;
  485.       circle( PointerX, PointerY, r);
  486.       r >>= 1;
  487.       circle( PointerX, PointerY, r);
  488.       r = (BCINT) (1024 * Scale);
  489.       line( PointerX - r, PointerY, PointerX + r, PointerY);
  490.       line( PointerX, PointerY - r, PointerX, PointerY + r);
  491.    }
  492.    else
  493.    {
  494.       SetColor( YELLOW);
  495.       line( PointerX - 15, PointerY - 13, PointerX + 15, PointerY + 13);
  496.       line( PointerX - 15, PointerY + 13, PointerX + 15, PointerY - 13);
  497.    }
  498.    /* restore normal write mode */
  499.    setwritemode( COPY_PUT);
  500. }
  501.  
  502.  
  503.  
  504. /*
  505.    load one "playpal" palette and change all palette colours
  506. */
  507.  
  508. void SetDoomPalette( BCINT playpalnum)
  509. {
  510.    MDirPtr             dir;
  511.    unsigned char huge *dpal;
  512.    BCINT                 n;
  513.  
  514.    if (playpalnum < 0 && playpalnum > 13)
  515.       return;
  516.    dir = FindMasterDir( MasterDir, "PLAYPAL");
  517.    if (dir)
  518.    {
  519.       dpal = (unsigned char*)GetFarMemory( 768 * sizeof( char));
  520.       BasicWadSeek( dir->wadfile, dir->dir.start);
  521.       for (n = 0; n <= playpalnum; n++)
  522.         BasicWadRead( dir->wadfile, dpal, 768L);
  523.  
  524. #if defined(__GNUC__)
  525.  
  526.       GrResetColors();
  527.       for(n=0;n<254;n++)
  528.          GrAllocCell();
  529.       
  530.       for(n=0;n<256;n++)
  531.          GrSetColor(n,dpal[3*n],dpal[3*n+1],dpal[3*n+2]);
  532.            
  533. #elif defined(__TURBOC__)
  534.  
  535.       for (n = 0; n < 768; n++)
  536.            dpal[ n] /= 4;
  537.  
  538.       _AX = 0x1012;
  539.       _BX = 0;
  540.       _CX = 256;
  541.       _ES = FP_SEG( dpal);
  542.       _DX = FP_OFF( dpal);
  543.       __int__( 0x10);
  544.  
  545. #endif
  546.  
  547.       FreeFarMemory( dpal );
  548.     }
  549. }
  550.  
  551.  
  552.  
  553. /*
  554.    translate a standard color to Doom palette 0 (approx.)
  555. */
  556.  
  557. BCINT TranslateToDoomColor( BCINT color)
  558. {
  559.    if (GfxMode < 0) {
  560.       if (color == WHITE) return 4;
  561.       switch (color)
  562.       {
  563. #ifdef __TURBOC__
  564.       case BLACK: return 0;
  565. #endif
  566.       case BLUE:
  567.       return 202;
  568.       case GREEN:
  569.       return 118;
  570.       case CYAN:
  571.       return 194;
  572.       case RED:
  573.       return 183;
  574.       case MAGENTA:
  575.       return 253;
  576.       case BROWN:
  577.       return 144;
  578.       case LIGHTGRAY:
  579.       return 88;
  580.       case DARKGRAY:
  581.       return 96;
  582.       case LIGHTBLUE:
  583.       return 197;
  584.       case LIGHTGREEN:
  585.       return 112;
  586.       case LIGHTCYAN:
  587.       return 193;
  588.       case LIGHTRED:
  589.       return 176;
  590.       case LIGHTMAGENTA:
  591.       return 250;
  592.       case YELLOW:
  593.       return 231;
  594.       }
  595.    }
  596.    return color;
  597. }
  598.  
  599.  
  600.  
  601. /*
  602.    translate (dx, dy) into an integer angle value (0-65535)
  603. */
  604.  
  605. UBCINT ComputeAngle( BCINT dx, BCINT dy)
  606. {
  607.    return (UBCINT) (atan2( (double) dy, (double) dx) * 10430.37835 + 0.5);
  608.    /* Yes, I know this function could be in another file, but */
  609.    /* this is the only source file that includes <math.h>...  */
  610. }
  611.  
  612.  
  613.  
  614. /*
  615.    compute the distance from (0, 0) to (dx, dy)
  616. */
  617.  
  618. UBCINT ComputeDist( BCINT dx, BCINT dy)
  619. {
  620.    return (UBCINT) (hypot( (double) dx, (double) dy) + 0.5);
  621.    /* Yes, I know this function could be in another file, but */
  622.    /* this is the only source file that includes <math.h>...  */
  623. }
  624.  
  625.  
  626.  
  627. /*
  628.    insert the vertices of a new polygon
  629. */
  630.  
  631. void InsertPolygonVertices( BCINT centerx, BCINT centery, BCINT sides, BCINT radius)
  632. {
  633.    BCINT n;
  634.  
  635.    for (n = 0; n < sides; n++)
  636.       InsertObject( OBJ_VERTEXES, -1, centerx + (BCINT) ((double) radius * cos( 6.28 * (double) n / (double) sides)), centery + (BCINT) ((double) radius * sin( 6.2832 * (double) n / (double) sides)));
  637.    /* Yes, I know... etc. */
  638. }
  639.  
  640.  
  641.  
  642. /*
  643.    move (x, y) to a new position: rotate and scale around (0, 0)
  644. */
  645.  
  646. void RotateAndScaleCoords( BCINT *x, BCINT *y, double angle, double scale)
  647. {
  648.    double r, theta;
  649.  
  650.    r = hypot( (double) *x, (double) *y);
  651.    theta = atan2( (double) *y, (double) *x);
  652.    *x = (BCINT) (r * scale * cos( theta + angle) + 0.5);
  653.    *y = (BCINT) (r * scale * sin( theta + angle) + 0.5);
  654.    /* Yes, I know... etc. */
  655. }
  656.  
  657. /* end of file */
  658.