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