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 >
Wrap
C/C++ Source or Header
|
1994-04-15
|
15KB
|
588 lines
/*
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 */
int 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 */
/*
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");
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( (mapXstart - OrigX) / Scale + ScrCenterX,
(OrigY - mapYstart) / Scale + ScrCenterY,
(mapXend - OrigX) / Scale + ScrCenterX,
(OrigY - mapYend) / Scale + ScrCenterY);
}
/*
draw a circle on the screen from map coords
*/
void DrawMapCircle( int mapXcenter, int mapYcenter, int mapRadius)
{
circle( (mapXcenter - OrigX) / Scale + ScrCenterX,
(OrigY - mapYcenter) / Scale + ScrCenterY,
mapRadius / Scale);
}
/*
draw an arrow on the screen from map coords
*/
void DrawMapVector( int mapXstart, int mapYstart, int mapXend, int mapYend)
{
int scrXstart = (mapXstart - OrigX) / Scale + ScrCenterX;
int scrYstart = (OrigY - mapYstart) / Scale + ScrCenterY;
int scrXend = (mapXend - OrigX) / Scale + ScrCenterX;
int scrYend = (OrigY - mapYend) / Scale + ScrCenterY;
double r = hypot( scrXstart - scrXend, scrYstart - scrYend);
int scrXoff = (r >= 1.0) ? (scrXstart - scrXend) * 16.0 / r / Scale : 0;
int scrYoff = (r >= 1.0) ? (scrYstart - scrYend) * 16.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 + 50 * cos(angle / 10430.37835);
int mapYend = mapYstart + 50 * sin(angle / 10430.37835);
int scrXstart = (mapXstart - OrigX) / Scale + ScrCenterX;
int scrYstart = (OrigY - mapYstart) / Scale + ScrCenterY;
int scrXend = (mapXend - OrigX) / Scale + ScrCenterX;
int scrYend = (OrigY - mapYend) / Scale + ScrCenterY;
double r = hypot( scrXstart - scrXend, scrYstart - scrYend);
int scrXoff = (r >= 1.0) ? (scrXstart - scrXend) * 16.0 / r / Scale : 0;
int scrYoff = (r >= 1.0) ? (scrYstart - scrYend) * 16.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 = 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 = 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. */
}
/* end of file */