From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/parsec/e_draw.cpp | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 src/parsec/e_draw.cpp (limited to 'src/parsec/e_draw.cpp') diff --git a/src/parsec/e_draw.cpp b/src/parsec/e_draw.cpp new file mode 100644 index 0000000..44306b2 --- /dev/null +++ b/src/parsec/e_draw.cpp @@ -0,0 +1,464 @@ +/* + * PARSEC - Drawing Function Wrappers + * + * $Author: uberlinuxguy $ - $Date: 2004/09/15 12:25:22 $ + * + * Orginally written by: + * Copyright (c) Markus Hadwiger 1999 + * Copyright (c) Andreas Varga 1999 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// subsystem headers +#include "vid_defs.h" + +// drawing subsystem +#include "d_bmap.h" +#include "d_iter.h" + +// model header +#include "utl_model.h" + +// local module header +#include "e_draw.h" + +// proprietary module headers +#include "con_aux.h" +#include "e_color.h" +#include "e_supp.h" + + + +// decoration texture definitions --------------------------------------------- +// +#define CORNER_WIDTH 16 +#define CORNER_HEIGHT 16 + +enum { + CORNER_LEFT_TOP, + CORNER_RIGHT_TOP, + CORNER_LEFT_BOTTOM, + CORNER_RIGHT_BOTTOM +}; + +const char *corner_texnames[ 4 ] = { + "corner1", + "corner2", + "corner3", + "corner4", +}; + + +// draw decorations on corners of translucent panels -------------------------- +// +void DRAW_PanelDecorations( sgrid_t putx, sgrid_t puty, int width, int height ) +{ + if ( AUX_DISABLE_PANEL_DECORATIONS ) + return; + + int halfwidth = CORNER_WIDTH >> 1; + + texscreenrect_s rect; + + rect.itertype = iter_texrgba | iter_specularadd; + rect.alpha = 255; + rect.w = rect.scaled_w = CORNER_WIDTH; + rect.h = rect.scaled_h = CORNER_HEIGHT; + rect.texofsx = 0; + rect.texofsy = 0; + + static TextureMap *texmap_lt = NULL; + if ( texmap_lt == NULL ) { + texmap_lt = FetchTextureMap( corner_texnames[ CORNER_LEFT_TOP ] ); + } + if ( texmap_lt != NULL ) { + + rect.x = putx - halfwidth; + rect.y = puty - halfwidth; + rect.texmap = texmap_lt; + + DRAW_TexturedScreenRect( &rect, NULL ); + } + + static TextureMap *texmap_rt = NULL; + if ( texmap_rt == NULL ) { + texmap_rt = FetchTextureMap( corner_texnames[ CORNER_RIGHT_TOP ] ); + } + if ( texmap_rt != NULL ) { + + rect.x = putx + width - halfwidth; + rect.y = puty - halfwidth; + rect.texmap = texmap_rt; + + DRAW_TexturedScreenRect( &rect, NULL ); + } + + static TextureMap *texmap_lb = NULL; + if ( texmap_lb == NULL ) { + texmap_lb = FetchTextureMap( corner_texnames[ CORNER_LEFT_BOTTOM ] ); + } + if ( texmap_lb != NULL ) { + + rect.x = putx - halfwidth; + rect.y = puty + height - halfwidth; + rect.texmap = texmap_lb; + + DRAW_TexturedScreenRect( &rect, NULL ); + } + + static TextureMap *texmap_rb = NULL; + if ( texmap_rb == NULL ) { + texmap_rb = FetchTextureMap( corner_texnames[ CORNER_RIGHT_BOTTOM ] ); + } + if ( texmap_rb != NULL ) { + + rect.x = putx + width - halfwidth; + rect.y = puty + height - halfwidth; + rect.texmap = texmap_rb; + + DRAW_TexturedScreenRect( &rect, NULL ); + } + + if ( width > CORNER_WIDTH ) { + + IterLine2 itline; + itline.NumVerts = 2; + itline.flags = ITERFLAG_LS_DEFAULT; + itline.itertype = iter_rgba | iter_alphablend; + itline.raststate = rast_default; + itline.rastmask = rast_nomask; + + itline.Vtxs[ 0 ].X = INT_TO_RASTV( putx + halfwidth + 1 ); + itline.Vtxs[ 0 ].Y = INT_TO_RASTV( puty - 3 ); + itline.Vtxs[ 0 ].Z = RASTV_0; + itline.Vtxs[ 0 ].R = PanelTextColor.R; + itline.Vtxs[ 0 ].G = PanelTextColor.G; + itline.Vtxs[ 0 ].B = PanelTextColor.B; + itline.Vtxs[ 0 ].A = PanelTextColor.A; + itline.Vtxs[ 0 ].flags = ITERVTXFLAG_NONE; + + itline.Vtxs[ 1 ].X = INT_TO_RASTV( putx + width - halfwidth + 1 ); + itline.Vtxs[ 1 ].Y = INT_TO_RASTV( puty - 3 ); + itline.Vtxs[ 1 ].Z = RASTV_0; + itline.Vtxs[ 1 ].R = PanelTextColor.R; + itline.Vtxs[ 1 ].G = PanelTextColor.G; + itline.Vtxs[ 1 ].B = PanelTextColor.B; + itline.Vtxs[ 1 ].A = PanelTextColor.A; + itline.Vtxs[ 1 ].flags = ITERVTXFLAG_NONE; + + Rectangle2 cliprect; + + cliprect.left = 0; + cliprect.right = Screen_Width; + cliprect.top = 0; + cliprect.bottom = Screen_Height; + + IterLine2 *clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + + itline.Vtxs[ 0 ].Y = INT_TO_RASTV( puty - 5 ); + itline.Vtxs[ 1 ].Y = INT_TO_RASTV( puty - 5 ); + + clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + + itline.Vtxs[ 0 ].Y = INT_TO_RASTV( puty + height + 4 ); + itline.Vtxs[ 1 ].Y = INT_TO_RASTV( puty + height + 4 ); + + clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + + itline.Vtxs[ 0 ].Y = INT_TO_RASTV( puty + height + 6 ); + itline.Vtxs[ 1 ].Y = INT_TO_RASTV( puty + height + 6 ); + + clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + + itline.Vtxs[ 0 ].X = INT_TO_RASTV( putx - 3 ); + itline.Vtxs[ 0 ].Y = INT_TO_RASTV( puty + halfwidth + 1 ); + itline.Vtxs[ 1 ].X = INT_TO_RASTV( putx - 3 ); + itline.Vtxs[ 1 ].Y = INT_TO_RASTV( puty + height - halfwidth + 1 ); + + clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + + itline.Vtxs[ 0 ].X = INT_TO_RASTV( putx - 5 ); + itline.Vtxs[ 1 ].X = INT_TO_RASTV( putx - 5 ); + + clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + + itline.Vtxs[ 0 ].X = INT_TO_RASTV( putx + width + 3 ); + itline.Vtxs[ 1 ].X = INT_TO_RASTV( putx + width + 3 ); + + clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + + itline.Vtxs[ 0 ].X = INT_TO_RASTV( putx + width + 5 ); + itline.Vtxs[ 1 ].X = INT_TO_RASTV( putx + width + 5 ); + + clipline = CLIP_RectangleIterLine2( &itline, &cliprect ); + if ( clipline != NULL ) + D_DrawIterLine2( clipline ); + } +} + + +// draw transparent rectangle with clipping ----------------------------------- +// +void DRAW_ClippedTrRect( sgrid_t putx, sgrid_t puty, int width, int height, dword brightx ) +{ + // reject if entirely invisible + if ( ( putx >= Screen_Width ) || ( puty >= Screen_Height ) ) + return; + + // clip rectangle to the left + if ( putx < 0 ) { + width += putx; + putx = 0; + } + + // clip rectangle to the top + if ( puty < 0 ) { + height += puty; + puty = 0; + } + + // reject if entirely invisible + if ( ( width <= 0 ) || ( height <= 0 ) ) + return; + + // clip rectangle to the right + if ( ( putx + width ) > Screen_Width ) { + width = Screen_Width - putx; + } + + // clip rectangle to the bottom + if ( ( puty + height ) > Screen_Height ) { + height = Screen_Height - puty; + } + + D_DrawTrRect( putx, puty, width, height, brightx ); + + DRAW_PanelDecorations( putx, puty, width, height ); +} + + +// draw translucent rectangle ------------------------------------------------- +// +void DRAW_ColoredScreenRect( colscreenrect_s *rect ) +{ + IterRectangle2 itrect; + + itrect.Vtxs[ 0 ].X = INT_TO_RASTV( rect->x ); + itrect.Vtxs[ 0 ].Y = INT_TO_RASTV( rect->y ); + itrect.Vtxs[ 0 ].Z = RASTV_1; + itrect.Vtxs[ 0 ].R = rect->color.R; + itrect.Vtxs[ 0 ].G = rect->color.G; + itrect.Vtxs[ 0 ].B = rect->color.B; + itrect.Vtxs[ 0 ].A = rect->color.A; + + itrect.Vtxs[ 1 ].X = INT_TO_RASTV( rect->x + rect->w ); + itrect.Vtxs[ 1 ].Y = INT_TO_RASTV( rect->y ); + itrect.Vtxs[ 1 ].Z = RASTV_1; + itrect.Vtxs[ 1 ].R = itrect.Vtxs[ 0 ].R; + itrect.Vtxs[ 1 ].G = itrect.Vtxs[ 0 ].G; + itrect.Vtxs[ 1 ].B = itrect.Vtxs[ 0 ].B; + itrect.Vtxs[ 1 ].A = itrect.Vtxs[ 0 ].A; + + itrect.Vtxs[ 2 ].X = INT_TO_RASTV( rect->x + rect->w ); + itrect.Vtxs[ 2 ].Y = INT_TO_RASTV( rect->y + rect->h ); + itrect.Vtxs[ 2 ].Z = RASTV_1; + itrect.Vtxs[ 2 ].R = itrect.Vtxs[ 0 ].R; + itrect.Vtxs[ 2 ].G = itrect.Vtxs[ 0 ].G; + itrect.Vtxs[ 2 ].B = itrect.Vtxs[ 0 ].B; + itrect.Vtxs[ 2 ].A = itrect.Vtxs[ 0 ].A; + + itrect.Vtxs[ 3 ].X = INT_TO_RASTV( rect->x ); + itrect.Vtxs[ 3 ].Y = INT_TO_RASTV( rect->y + rect->h ); + itrect.Vtxs[ 3 ].Z = RASTV_1; + itrect.Vtxs[ 3 ].R = itrect.Vtxs[ 0 ].R; + itrect.Vtxs[ 3 ].G = itrect.Vtxs[ 0 ].G; + itrect.Vtxs[ 3 ].B = itrect.Vtxs[ 0 ].B; + itrect.Vtxs[ 3 ].A = itrect.Vtxs[ 0 ].A; + + itrect.flags = ITERFLAG_NONE; + itrect.itertype = rect->itertype; + itrect.raststate = rast_default; + itrect.rastmask = rast_nomask; + itrect.texmap = NULL; + + D_DrawIterRectangle2( &itrect ); +} + + +// draw (clipped) rectangular texture in 2-D ---------------------------------- +// +void DRAW_TexturedScreenRect( texscreenrect_s *rect, Rectangle2 *cliprect ) +{ + ASSERT( rect != NULL ); +// ASSERT( cliprect != NULL ); + + //NOTE: + // if ( cliprect == NULL ) no clipping will be performed. + // in this case the rectangle MUST lie entirely the screen + // extents. + + IterRectangle2 itrect; + + // to avoid texture seams due to filtering on all drivers + // (especially the G400 needs this) + geomv_t texbrdcorr = FLOAT_TO_GEOMV( 0.0 ); + + itrect.Vtxs[ 0 ].X = INT_TO_RASTV( rect->x ); + itrect.Vtxs[ 0 ].Y = INT_TO_RASTV( rect->y ); + itrect.Vtxs[ 0 ].Z = RASTV_1; + itrect.Vtxs[ 0 ].W = GEOMV_1; + itrect.Vtxs[ 0 ].U = INT_TO_GEOMV( rect->texofsx ); + itrect.Vtxs[ 0 ].V = INT_TO_GEOMV( rect->texofsy ); + itrect.Vtxs[ 0 ].R = rect->alpha; + itrect.Vtxs[ 0 ].G = rect->alpha; + itrect.Vtxs[ 0 ].B = rect->alpha; + itrect.Vtxs[ 0 ].A = rect->alpha; + + itrect.Vtxs[ 1 ].X = INT_TO_RASTV( rect->x + rect->scaled_w ); + itrect.Vtxs[ 1 ].Y = INT_TO_RASTV( rect->y ); + itrect.Vtxs[ 1 ].Z = itrect.Vtxs[ 0 ].Z; + itrect.Vtxs[ 1 ].W = itrect.Vtxs[ 0 ].W; + itrect.Vtxs[ 1 ].U = INT_TO_GEOMV( rect->texofsx + rect->w ) - texbrdcorr; + itrect.Vtxs[ 1 ].V = INT_TO_GEOMV( rect->texofsy ); + itrect.Vtxs[ 1 ].R = itrect.Vtxs[ 0 ].R; + itrect.Vtxs[ 1 ].G = itrect.Vtxs[ 0 ].G; + itrect.Vtxs[ 1 ].B = itrect.Vtxs[ 0 ].B; + itrect.Vtxs[ 1 ].A = itrect.Vtxs[ 0 ].A; + + itrect.Vtxs[ 2 ].X = INT_TO_RASTV( rect->x + rect->scaled_w ); + itrect.Vtxs[ 2 ].Y = INT_TO_RASTV( rect->y + rect->scaled_h ); + itrect.Vtxs[ 2 ].Z = itrect.Vtxs[ 0 ].Z; + itrect.Vtxs[ 2 ].W = itrect.Vtxs[ 0 ].W; + itrect.Vtxs[ 2 ].U = INT_TO_GEOMV( rect->texofsx + rect->w ) - texbrdcorr; + itrect.Vtxs[ 2 ].V = INT_TO_GEOMV( rect->texofsy + rect->h ) - texbrdcorr; + itrect.Vtxs[ 2 ].R = itrect.Vtxs[ 0 ].R; + itrect.Vtxs[ 2 ].G = itrect.Vtxs[ 0 ].G; + itrect.Vtxs[ 2 ].B = itrect.Vtxs[ 0 ].B; + itrect.Vtxs[ 2 ].A = itrect.Vtxs[ 0 ].A; + + itrect.Vtxs[ 3 ].X = INT_TO_RASTV( rect->x ); + itrect.Vtxs[ 3 ].Y = INT_TO_RASTV( rect->y + rect->scaled_h ); + itrect.Vtxs[ 3 ].Z = itrect.Vtxs[ 0 ].Z; + itrect.Vtxs[ 3 ].W = itrect.Vtxs[ 0 ].W; + itrect.Vtxs[ 3 ].U = INT_TO_GEOMV( rect->texofsx ); + itrect.Vtxs[ 3 ].V = INT_TO_GEOMV( rect->texofsy + rect->h ) - texbrdcorr; + itrect.Vtxs[ 3 ].R = itrect.Vtxs[ 0 ].R; + itrect.Vtxs[ 3 ].G = itrect.Vtxs[ 0 ].G; + itrect.Vtxs[ 3 ].B = itrect.Vtxs[ 0 ].B; + itrect.Vtxs[ 3 ].A = itrect.Vtxs[ 0 ].A; + + itrect.flags = ITERFLAG_NONE; + itrect.itertype = rect->itertype; + itrect.raststate = rast_texclamp; + itrect.rastmask = rast_nomask; + itrect.texmap = rect->texmap; + + // if cliprect == NULL no clipping should be performed + if ( cliprect != NULL ) { + + float xscale = ( (float) rect->w ) / ( rect->scaled_w ); + float yscale = ( (float) rect->h ) / ( rect->scaled_h ); + + // reject if completely invisible + if ( itrect.Vtxs[ 0 ].X > cliprect->right || + itrect.Vtxs[ 0 ].Y > cliprect->bottom || + itrect.Vtxs[ 1 ].X < cliprect->left || + itrect.Vtxs[ 2 ].Y < cliprect->top ) { + + return; + } + + // clip against left edge + if ( itrect.Vtxs[ 0 ].X < cliprect->left ) { + + rastv_t offs = cliprect->left - itrect.Vtxs[ 0 ].X; + itrect.Vtxs[ 0 ].U += offs * xscale; + itrect.Vtxs[ 3 ].U += offs * xscale; + itrect.Vtxs[ 0 ].X = cliprect->left; + itrect.Vtxs[ 3 ].X = cliprect->left; + } + + // clip against top edge + if ( itrect.Vtxs[ 0 ].Y < cliprect->top ) { + + rastv_t offs = cliprect->top - itrect.Vtxs[ 0 ].Y; + itrect.Vtxs[ 0 ].V += offs * yscale; + itrect.Vtxs[ 1 ].V += offs * yscale; + itrect.Vtxs[ 0 ].Y = cliprect->top; + itrect.Vtxs[ 1 ].Y = cliprect->top; + } + + // clip against right edge + if ( itrect.Vtxs[ 1 ].X > cliprect->right ) { + + rastv_t offs = itrect.Vtxs[ 1 ].X - cliprect->right; + itrect.Vtxs[ 1 ].U -= offs * xscale; + itrect.Vtxs[ 2 ].U -= offs * xscale; + itrect.Vtxs[ 1 ].X = cliprect->right; + itrect.Vtxs[ 2 ].X = cliprect->right; + } + + // clip against bottom edge + if ( itrect.Vtxs[ 2 ].Y > cliprect->bottom ) { + + rastv_t offs = itrect.Vtxs[ 2 ].Y - cliprect->bottom; + itrect.Vtxs[ 2 ].V -= offs * yscale; + itrect.Vtxs[ 3 ].V -= offs * yscale; + itrect.Vtxs[ 2 ].Y = cliprect->bottom; + itrect.Vtxs[ 3 ].Y = cliprect->bottom; + } + } + + int oldwrapmode = AUX_DISABLE_TEXTURE_WRAPPING; + AUX_DISABLE_TEXTURE_WRAPPING = 1; + + D_DrawIterRectangle2( &itrect ); + + AUX_DISABLE_TEXTURE_WRAPPING = oldwrapmode; +} + + + -- cgit v1.2.3