home *** CD-ROM | disk | FTP | other *** search
- /*
- Doom Editor Utility, by Brendon Wyber and Raphaƫl Quinet.
-
- You are allowed to use any parts of this code in another program, as
- long as you give credits to the authors in the documentation and in
- the program itself. Read the file README.1ST for more information.
-
- This program comes with absolutely no warranty.
-
- GFX.C - Graphics routines.
- */
-
- /* the includes */
- #include "deu.h"
- #include <math.h>
- #include <dos.h>
-
- /* if your graphics driver doesn't like circles, draw squares instead */
- #ifdef NO_CIRCLES
- #define circle( x, y, r) line( x - r, y - r, x - r, y + r); \
- line( x - r, y + r, x + r, y + r); \
- line( x + r, y + r, x + r, y - r); \
- line( x + r, y - r, x - r, y - r)
- #endif /* NO_CIRCLES */
-
- /* the global variables */
- int GfxMode = 0; /* graphics mode number, or 0 for text */
- /* 1 = 320x200, 2 = 640x480, 3 = 800x600, 4 = 1024x768 */
- /* positive = 16 colors, negative = 256 colors */
- int OrigX; /* the X origin */
- int OrigY; /* the Y origin */
- float Scale; /* the scale value */
- int PointerX; /* X position of pointer */
- int PointerY; /* Y position of pointer */
- int ScrMaxX; /* maximum X screen coord */
- int ScrMaxY; /* maximum Y screen coord */
- int ScrCenterX; /* X coord of screen center */
- int ScrCenterY; /* Y coord of screen center */
-
- #ifdef CIRRUS_PATCH
- char mp[ 256];
-
- char HWCursor[] =
- {
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
- 0x1F, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00,
- 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00,
- 0x07, 0xC0, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00,
- 0x03, 0x70, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x3F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF,
- 0x83, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF,
- 0xC0, 0x3F, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF,
- 0xE0, 0x07, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF,
- 0xF0, 0x1F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF,
- 0xF8, 0x07, 0xFF, 0xFF, 0xF8, 0x83, 0xFF, 0xFF,
- 0xFD, 0xC7, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
- };
- #endif /* CIRRUS_PATCH */
-
-
- /*
- initialise the graphics display
- */
-
- void InitGfx()
- {
- static Bool firsttime = TRUE;
- static int gdriver;
- static int gmode;
- int errorcode = grNoInitGraph;
-
- printf( "Switching to graphics mode...\n");
- #ifdef CIRRUS_PATCH
- if (CirrusCursor == TRUE)
- SetHWCursorMap( HWCursor);
- #endif /* CIRRUS_PATCH */
- if (firsttime)
- {
- if (VideoMode > 0)
- {
- gdriver = installuserdriver( BGIDriver, NULL);
- gmode = VideoMode;
- initgraph( &gdriver, &gmode, NULL);
- errorcode = graphresult();
- }
- if (errorcode != grOk)
- {
- gdriver = VGA;
- gmode = VGAHI;
- }
- }
- if (gdriver == VGA || !firsttime)
- {
- initgraph( &gdriver, &gmode, NULL);
- errorcode = graphresult();
- if (errorcode != grOk)
- ProgError( "graphics error: %s", grapherrormsg( errorcode));
- }
- if (gdriver == VGA)
- GfxMode = 2; /* 640x480x16 */
- else
- {
- GfxMode = -gmode; /* 640x480x256, 800x600x256, or 1024x768x256 */
- SetDoomPalette( 0);
- }
- setlinestyle( 0, 0, 1);
- setbkcolor( TranslateToDoomColor( BLACK));
- settextstyle( 0, 0, 1);
- firsttime = FALSE;
- ScrMaxX = getmaxx();
- ScrMaxY = getmaxy();
- ScrCenterX = ScrMaxX / 2;
- ScrCenterY = ScrMaxY / 2;
- }
-
-
-
- /*
- terminate the graphics display
- */
-
- void TermGfx()
- {
- if (GfxMode)
- {
- closegraph();
- GfxMode = 0;
- }
- }
-
-
-
- /*
- switch from VGA 16 colours to VGA 256 colours
- */
-
- Bool SwitchToVGA256()
- {
- static int gdriver = -1;
- int gmode, errorcode;
-
- if (GfxMode > 0 && gdriver != VGA) /* if 16 colors and not failed before */
- {
- if (gdriver == -1)
- {
- gdriver = installuserdriver( "VGA256", NULL);
- errorcode = graphresult();
- }
- if (UseMouse)
- HideMousePointer();
- closegraph();
- gmode = 0;
- initgraph( &gdriver, &gmode, NULL);
- errorcode = graphresult();
- if (errorcode != grOk)
- {
- /* failed for 256 colors - back to 16 colors */
- gdriver = VGA;
- gmode = VGAHI;
- initgraph( &gdriver, &gmode, NULL);
- errorcode = graphresult();
- }
- if (errorcode != grOk) /* shouldn't happen */
- ProgError( "graphics error: %s", grapherrormsg( errorcode));
- if (UseMouse)
- ShowMousePointer();
- GfxMode = -1 /* 320x200x256 */;
- SetDoomPalette( 0);
- ScrMaxX = getmaxx();
- ScrMaxY = getmaxy();
- ScrCenterX = ScrMaxX / 2;
- ScrCenterY = ScrMaxY / 2;
- return TRUE;
- }
- return FALSE;
- }
-
-
-
- /*
- switch from VGA 256 colours to VGA 16 colours
- */
-
- Bool SwitchToVGA16()
- {
- int gdriver, gmode, errorcode;
-
- if (GfxMode == -1) /* switch only if we are in 320x200x256 colors */
- {
- if (UseMouse)
- HideMousePointer();
- closegraph();
- gdriver = VGA;
- gmode = VGAHI;
- initgraph( &gdriver, &gmode, NULL);
- errorcode = graphresult();
- if (errorcode != grOk) /* shouldn't happen */
- ProgError( "graphics error: %s", grapherrormsg( errorcode));
- if (UseMouse)
- ShowMousePointer();
- GfxMode = 2; /* 640x480x16 */
- ScrMaxX = getmaxx();
- ScrMaxY = getmaxy();
- ScrCenterX = ScrMaxX / 2;
- ScrCenterY = ScrMaxY / 2;
- return TRUE;
- }
- return FALSE;
- }
-
-
-
- /*
- clear the screen
- */
-
- void ClearScreen()
- {
- cleardevice();
- }
-
-
-
- /*
- set the current drawing color
- */
-
- void SetColor( int color)
- {
- if (GfxMode < 0)
- setcolor( TranslateToDoomColor(color));
- else
- setcolor( color);
- }
-
-
-
- /*
- draw a line on the screen from map coords
- */
-
- void DrawMapLine( int mapXstart, int mapYstart, int mapXend, int mapYend)
- {
- line( SCREENX( mapXstart), SCREENY( mapYstart), SCREENX( mapXend), SCREENY( mapYend));
- }
-
-
-
- /*
- draw a circle on the screen from map coords
- */
-
- void DrawMapCircle( int mapXcenter, int mapYcenter, int mapRadius)
- {
- circle( SCREENX( mapXcenter), SCREENY( mapYcenter), (int) (mapRadius * Scale));
- }
-
-
-
- /*
- draw an arrow on the screen from map coords
- */
-
- void DrawMapVector( int mapXstart, int mapYstart, int mapXend, int mapYend)
- {
- int scrXstart = SCREENX( mapXstart);
- int scrYstart = SCREENY( mapYstart);
- int scrXend = SCREENX( mapXend);
- int scrYend = SCREENY( mapYend);
- double r = hypot( (double) (scrXstart - scrXend), (double) (scrYstart - scrYend));
- int scrXoff = (r >= 1.0) ? (int) ((scrXstart - scrXend) * 8.0 / r * Scale) : 0;
- int scrYoff = (r >= 1.0) ? (int) ((scrYstart - scrYend) * 8.0 / r * Scale) : 0;
-
- line( scrXstart, scrYstart, scrXend, scrYend);
- scrXstart = scrXend + 2 * scrXoff;
- scrYstart = scrYend + 2 * scrYoff;
- line( scrXstart - scrYoff, scrYstart + scrXoff, scrXend, scrYend);
- line( scrXstart + scrYoff, scrYstart - scrXoff, scrXend, scrYend);
- /*
- line( scrXstart - scrYoff, scrYstart + scrXoff, scrXend + scrXoff, scrYend + scrYoff);
- line( scrXstart + scrYoff, scrYstart - scrXoff, scrXend + scrXoff, scrYend + scrYoff);
- */
- }
-
-
-
- /*
- draw an arrow on the screen from map coords and angle (0 - 65535)
- */
-
- void DrawMapArrow( int mapXstart, int mapYstart, unsigned angle)
- {
- int mapXend = mapXstart + (int) (50 * cos(angle / 10430.37835));
- int mapYend = mapYstart + (int) (50 * sin(angle / 10430.37835));
- int scrXstart = SCREENX( mapXstart);
- int scrYstart = SCREENY( mapYstart);
- int scrXend = SCREENX( mapXend);
- int scrYend = SCREENY( mapYend);
- double r = hypot( scrXstart - scrXend, scrYstart - scrYend);
- int scrXoff = (r >= 1.0) ? (int) ((scrXstart - scrXend) * 8.0 / r * Scale) : 0;
- int scrYoff = (r >= 1.0) ? (int) ((scrYstart - scrYend) * 8.0 / r * Scale) : 0;
-
- line( scrXstart, scrYstart, scrXend, scrYend);
- scrXstart = scrXend + 2 * scrXoff;
- scrYstart = scrYend + 2 * scrYoff;
- line( scrXstart - scrYoff, scrYstart + scrXoff, scrXend, scrYend);
- line( scrXstart + scrYoff, scrYstart - scrXoff, scrXend, scrYend);
- }
-
-
-
- /*
- draw a line on the screen from screen coords
- */
-
- void DrawScreenLine( int Xstart, int Ystart, int Xend, int Yend)
- {
- line( Xstart, Ystart, Xend, Yend);
- }
-
-
-
- /*
- draw a filled in box on the screen from screen coords
- */
-
- void DrawScreenBox( int Xstart, int Ystart, int Xend, int Yend)
- {
- setfillstyle( 1, getcolor());
- bar( Xstart, Ystart, Xend, Yend);
- }
-
-
-
- /*
- draw a filled-in 3D-box on the screen from screen coords
- */
-
- void DrawScreenBox3D( int Xstart, int Ystart, int Xend, int Yend)
- {
- setfillstyle( 1, TranslateToDoomColor( LIGHTGRAY));
- bar( Xstart + 1, Ystart + 1, Xend - 1, Yend - 1);
- SetColor( DARKGRAY);
- line( Xstart, Yend, Xend, Yend);
- line( Xend, Ystart, Xend, Yend);
- if (Xend - Xstart > 20 && Yend - Ystart > 20)
- {
- line( Xstart + 1, Yend - 1, Xend - 1, Yend - 1);
- line( Xend - 1, Ystart + 1, Xend - 1, Yend - 1);
- SetColor( WHITE);
- line( Xstart + 1, Ystart + 1, Xstart + 1, Yend - 1);
- line( Xstart + 1, Ystart + 1, Xend - 1, Ystart + 1);
- }
- SetColor( WHITE);
- line( Xstart, Ystart, Xend, Ystart);
- line( Xstart, Ystart, Xstart, Yend);
- SetColor( BLACK);
- }
-
-
-
- /*
- draw a hollow 3D-box on the screen from screen coords
- */
-
- void DrawScreenBoxHollow( int Xstart, int Ystart, int Xend, int Yend)
- {
- setfillstyle( 1, TranslateToDoomColor( BLACK));
- bar( Xstart + 1, Ystart + 1, Xend - 1, Yend - 1);
- SetColor( WHITE);
- line( Xstart, Yend, Xend, Yend);
- line( Xend, Ystart, Xend, Yend);
- if (Xend - Xstart > 20 && Yend - Ystart > 20)
- {
- line( Xstart + 1, Yend - 1, Xend - 1, Yend - 1);
- line( Xend - 1, Ystart + 1, Xend - 1, Yend - 1);
- SetColor( DARKGRAY);
- line( Xstart + 1, Ystart + 1, Xstart + 1, Yend - 1);
- line( Xstart + 1, Ystart + 1, Xend - 1, Ystart + 1);
- }
- SetColor( DARKGRAY);
- line( Xstart, Ystart, Xend, Ystart);
- line( Xstart, Ystart, Xstart, Yend);
- SetColor( WHITE);
- }
-
-
-
- /*
- draw a meter bar on the screen from screen coords (in a hollow box); max. value = 1.0
- */
-
- void DrawScreenMeter( int Xstart, int Ystart, int Xend, int Yend, float value)
- {
- if (value < 0.0)
- value = 0.0;
- if (value > 1.0)
- value = 1.0;
- setfillstyle( 1, TranslateToDoomColor( BLACK));
- bar( Xstart + 1 + (int) ((Xend - Xstart - 2) * value), Ystart + 1, Xend - 1, Yend - 1);
- setfillstyle( 1, TranslateToDoomColor( LIGHTGREEN));
- bar( Xstart + 1, Ystart + 1, Xstart + 1 + (int) ((Xend - Xstart - 2) * value), Yend - 1);
- }
-
-
-
- /*
- write text to the screen
- */
-
- void DrawScreenText( int Xstart, int Ystart, char *msg, ...)
- {
- static int lastX;
- static int lastY;
- char temp[ 120];
- va_list args;
-
- va_start( args, msg);
- vsprintf( temp, msg, args);
- va_end( args);
- if (Xstart < 0)
- Xstart = lastX;
- if (Ystart < 0)
- Ystart = lastY;
- outtextxy( Xstart, Ystart, temp);
- lastX = Xstart;
- lastY = Ystart + 10; /* or textheight("W") ? */
- }
-
-
-
- /*
- draw (or erase) the pointer if we aren't using the mouse
- */
-
- void DrawPointer( Bool rulers)
- {
- int r;
-
- /* use XOR mode : drawing the pointer twice erases it */
- setwritemode( XOR_PUT);
- /* draw the pointer */
- if ( rulers)
- {
- SetColor( MAGENTA);
- r = (int) (512 * Scale);
- circle( PointerX, PointerY, r);
- r >>= 1;
- circle( PointerX, PointerY, r);
- r >>= 1;
- circle( PointerX, PointerY, r);
- r >>= 1;
- circle( PointerX, PointerY, r);
- r = (int) (1024 * Scale);
- line( PointerX - r, PointerY, PointerX + r, PointerY);
- line( PointerX, PointerY - r, PointerX, PointerY + r);
- }
- else
- {
- SetColor( YELLOW);
- line( PointerX - 15, PointerY - 13, PointerX + 15, PointerY + 13);
- line( PointerX - 15, PointerY + 13, PointerX + 15, PointerY - 13);
- }
- /* restore normal write mode */
- setwritemode( COPY_PUT);
- }
-
-
-
- /*
- load one "playpal" palette and change all palette colours
- */
-
- void SetDoomPalette( int playpalnum)
- {
- MDirPtr dir;
- unsigned char huge *dpal;
- int n;
-
- if (playpalnum < 0 && playpalnum > 13)
- return;
- dir = FindMasterDir( MasterDir, "PLAYPAL");
- if (dir)
- {
- dpal = GetFarMemory( 768 * sizeof( char));
- BasicWadSeek( dir->wadfile, dir->dir.start);
- for (n = 0; n <= playpalnum; n++)
- BasicWadRead( dir->wadfile, dpal, 768L);
- for (n = 0; n < 768; n++)
- dpal[ n] /= 4;
- _AX = 0x1012;
- _BX = 0;
- _CX = 256;
- _ES = FP_SEG( dpal);
- _DX = FP_OFF( dpal);
- __int__( 0x10);
- FreeFarMemory( dpal);
- }
- }
-
-
-
- /*
- translate a standard color to Doom palette 0 (approx.)
- */
-
- int TranslateToDoomColor( int color)
- {
- if (GfxMode < 0)
- switch (color)
- {
- case BLACK:
- return 0;
- case BLUE:
- return 202;
- case GREEN:
- return 118;
- case CYAN:
- return 194;
- case RED:
- return 183;
- case MAGENTA:
- return 253;
- case BROWN:
- return 144;
- case LIGHTGRAY:
- return 88;
- case DARKGRAY:
- return 96;
- case LIGHTBLUE:
- return 197;
- case LIGHTGREEN:
- return 112;
- case LIGHTCYAN:
- return 193;
- case LIGHTRED:
- return 176;
- case LIGHTMAGENTA:
- return 250;
- case YELLOW:
- return 231;
- case WHITE:
- return 4;
- }
- return color;
- }
-
-
-
- /*
- translate (dx, dy) into an integer angle value (0-65535)
- */
-
- unsigned ComputeAngle( int dx, int dy)
- {
- return (unsigned) (atan2( (double) dy, (double) dx) * 10430.37835 + 0.5);
- /* Yes, I know this function could be in another file, but */
- /* this is the only source file that includes <math.h>... */
- }
-
-
-
- /*
- compute the distance from (0, 0) to (dx, dy)
- */
-
- unsigned ComputeDist( int dx, int dy)
- {
- return (unsigned) (hypot( (double) dx, (double) dy) + 0.5);
- /* Yes, I know this function could be in another file, but */
- /* this is the only source file that includes <math.h>... */
- }
-
-
-
- /*
- insert the vertices of a new polygon
- */
-
- void InsertPolygonVertices( int centerx, int centery, int sides, int radius)
- {
- int n;
-
- for (n = 0; n < sides; n++)
- 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)));
- /* Yes, I know... etc. */
- }
-
-
-
- /*
- move (x, y) to a new position: rotate and scale around (0, 0)
- */
-
- void RotateAndScaleCoords( int *x, int *y, double angle, double scale)
- {
- double r, theta;
-
- r = hypot( (double) *x, (double) *y);
- theta = atan2( (double) *y, (double) *x);
- *x = (int) (r * scale * cos( theta + angle) + 0.5);
- *y = (int) (r * scale * sin( theta + angle) + 0.5);
- /* Yes, I know... etc. */
- }
-
-
-
- #ifdef CIRRUS_PATCH
- /*
- Cirrus Logic Hardware Mouse Cursor Stuff
- */
-
- #define CRTC 0x3D4
- #define ATTR 0x3C0
- #define SEQ 0x3C4
- #define GRC 0x3CE
- #define LOBYTE(w) ((unsigned char)(w))
- #define HIBYTE(w) ((unsigned char)((unsigned int)(w) >> 8))
-
- unsigned rdinx( unsigned pt, unsigned inx)
- {
- if (pt == ATTR)
- inportb( CRTC + 6);
- outportb( pt, inx);
- return inportb( pt + 1);
- }
-
- void wrinx( int pt, unsigned inx, unsigned val)
- {
- if (pt == ATTR)
- {
- inportb( CRTC + 6);
- outportb( pt, inx);
- outportb( pt, val);
- }
- else
- {
- outportb( pt, inx);
- outportb( pt + 1, val);
- }
- }
-
- void modinx( unsigned pt, unsigned inx, unsigned mask, unsigned nwv)
- {
- unsigned temp;
-
- temp = (rdinx( pt, inx) & ~mask) + (nwv & mask);
- wrinx( pt, inx, temp);
- }
-
- void clrinx( unsigned pt, unsigned inx, unsigned val)
- {
- unsigned x;
-
- x = rdinx( pt, inx);
- wrinx( pt, inx, x & ~val);
- }
-
- void SetHWCursorPos( unsigned x, unsigned y)
- {
- outport( SEQ, (x << 5) | 0x10);
- outport( SEQ, (y << 5) | 0x11);
- }
-
- void SetHWCursorCol( long fgcol, long bgcol)
- {
- modinx( SEQ, 0x12, 3, 2);
- outportb( 0x3C8, 0xFF);
- outportb( 0x3C9, LOBYTE( fgcol) >> 2);
- outportb( 0x3C9, HIBYTE( bgcol) >> 2);
- outportb( 0x3C8, 0);
- outportb( 0x3C9, LOBYTE( bgcol) >> 2);
- outportb( 0x3C9, HIBYTE( bgcol) >> 2);
- outportb( 0x3C9, bgcol >> 18);
- modinx( SEQ, 0x12, 3, 1);
- }
-
- void CopyHWCursorMap( unsigned bytes)
- {
- char *curmapptr = 0xA000FF00L;
- unsigned lbank = (1024 / 64) - 1;
-
- if ((rdinx( GRC, 0x0B) & 32)==0)
- lbank = lbank << 2;
- wrinx( GRC, 9, lbank << 2);
- memmove( curmapptr, &mp, bytes);
- }
-
- void SetHWCursorMap( char *map)
- {
- memmove( &mp, map, 128);
- memmove( &mp + 128, &mp, 128);
- CopyHWCursorMap( 256);
- SetHWCursorCol( 0xFF00000L, 0xFF);
- wrinx( SEQ, 0x13, 0x3F);
- }
-
- #endif /* CIRRUS_PATCH */
-
-
-
- /* end of file */
-