mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
404 lines
9.8 KiB
C++
404 lines
9.8 KiB
C++
/*
|
|
* $Logfile: /DescentIII/Main/2dlib/viewport.cpp $
|
|
* $Revision: 7 $
|
|
* $Date: 12/19/97 5:23p $
|
|
* $Author: Samir $
|
|
*
|
|
* this class manages a specific viewing region of either a screen or bitmap.
|
|
* functions such as font setting and bitmap bltting are supported
|
|
* under this class.
|
|
*
|
|
* this class also spawns a pen object which effectively locks the screen or
|
|
* bitmap associated with it.
|
|
*
|
|
* $Log: /DescentIII/Main/2dlib/viewport.cpp $
|
|
*
|
|
* 7 12/19/97 5:23p Samir
|
|
* Cleaned up a lot of code to call renderer code.
|
|
*
|
|
* 6 12/19/97 12:32p Samir
|
|
* Support alpha for text. Stubbed out clipping support.
|
|
*
|
|
* 5 11/18/97 12:32p Samir
|
|
* Took out useless lines.
|
|
*
|
|
* 4 11/14/97 12:05p Samir
|
|
* don't free font, just init it.
|
|
*
|
|
* 20 6/13/97 1:17p Samir
|
|
* Fucked up last checkin
|
|
*
|
|
* 19 6/13/97 1:00p Samir
|
|
* lock when called will always lock, so if the lock fails, then it's not
|
|
* viewport's job to fix it.
|
|
*
|
|
* 18 6/12/97 6:29p Samir
|
|
* DDGR v2.0 Changes in 2d system implemented.
|
|
*
|
|
* 17 6/06/97 12:18p Samir
|
|
* OpenGL HACKS to call renderer for some drawing functions. Must fix.
|
|
*
|
|
* 16 5/15/97 3:47p Samir
|
|
* Fixed lock_clear.
|
|
*
|
|
* 15 5/13/97 6:36p Samir
|
|
* added lock_clear functions.
|
|
*
|
|
* 14 4/01/97 4:37p Samir
|
|
* Simply better circle functions using viewport line and pixel functions.
|
|
* made an hline function that clips and a setpixel function that clips.
|
|
*
|
|
* 13 3/28/97 3:07p Samir
|
|
* Clear function now takes a color
|
|
*
|
|
* 12 3/28/97 2:50p Samir
|
|
* Fixed clip_rect fuckup.
|
|
*
|
|
* 11 2/18/97 1:04p Samir
|
|
* Changed prototype for setpixel
|
|
*
|
|
* 10 2/18/97 11:38a Samir
|
|
* Added getpixel and setpixel to grViewport. NOTE: you must lock the
|
|
* viewport when doing these ops.
|
|
*
|
|
* 9 2/04/97 4:56p Samir
|
|
* added 'hack' in viewport lock. see the function to see what I mean.
|
|
*
|
|
* 8 2/04/97 12:50p Samir
|
|
* Viewports now lock on CLIP_LEFT, CLIP_TOP
|
|
*
|
|
* 7 2/04/97 11:14a Samir
|
|
* Improved clipping system by adding a separate clipport based off of the
|
|
* viewport's rectangle in it's parent surface
|
|
*
|
|
* 6 2/03/97 7:56p Samir
|
|
*
|
|
* 5 1/31/97 11:02a Samir
|
|
* Adjusted clear function to use x,y,width,height parms.
|
|
*
|
|
* 4 1/30/97 6:28p Samir
|
|
* Stupid me, left some dummy text causing errors.
|
|
*
|
|
* 3 1/30/97 6:01p Samir
|
|
* The partition of memory and os surfaces as well as the change in
|
|
* ddgr_surface structure and all related changes.
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#include "gr.h"
|
|
#include "lib2d.h"
|
|
#include "renderer.h"
|
|
|
|
#include "pserror.h"
|
|
|
|
#define CLIP_LEFT (vp_InitLeft+vp_Left)
|
|
#define CLIP_TOP (vp_InitTop+vp_Top)
|
|
#define CLIP_RIGHT (vp_InitLeft+vp_Right)
|
|
#define CLIP_BOTTOM (vp_InitTop+vp_Bottom)
|
|
|
|
|
|
int grViewport::vp_Locked = 0;
|
|
grViewport *grViewport::vp_Current_VP = NULL;
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// grViewport constructor and destructor
|
|
// ---------------------------------------------------------------------------
|
|
|
|
grViewport::grViewport(grScreen *scr_parent)
|
|
{
|
|
ASSERT(scr_parent != NULL);
|
|
|
|
sf_Parent = scr_parent; // screen is a child of grSurface, so we
|
|
// can do this.
|
|
vp_InitLeft = vp_Left = 0; // define bounds = entire screen
|
|
vp_InitTop = vp_Top = 0;
|
|
vp_InitRight = vp_Right = sf_Parent->width()-1;
|
|
vp_InitBottom = vp_Bottom = sf_Parent->height()-1;
|
|
|
|
// initialize font object
|
|
// setup text settings.
|
|
char_Props.col[0] = GR_WHITE;
|
|
char_Props.col[1] = GR_WHITE;
|
|
char_Props.col[2] = GR_WHITE;
|
|
char_Props.col[3] = GR_WHITE;
|
|
char_Props.alpha = 255;
|
|
|
|
text_Spacing = 1;
|
|
text_Line_spacing = 1;
|
|
text_Font.init(DEFAULT_FONT);
|
|
}
|
|
|
|
|
|
grViewport::grViewport(grSurface *sf_parent)
|
|
{
|
|
ASSERT(sf_parent != NULL);
|
|
|
|
sf_Parent = sf_parent;
|
|
|
|
vp_InitLeft = vp_Left = 0; // define bounds = entire bitmap
|
|
vp_InitTop = vp_Top = 0;
|
|
vp_InitRight = vp_Right = sf_Parent->width()-1;
|
|
vp_InitBottom = vp_Bottom = sf_Parent->height()-1;
|
|
|
|
// initialize font object
|
|
// setup text settings.
|
|
char_Props.col[0] = GR_WHITE;
|
|
char_Props.col[1] = GR_WHITE;
|
|
char_Props.col[2] = GR_WHITE;
|
|
char_Props.col[3] = GR_WHITE;
|
|
char_Props.alpha = 255;
|
|
|
|
text_Spacing = 1;
|
|
text_Line_spacing = 1;
|
|
text_Font.init(DEFAULT_FONT);
|
|
}
|
|
|
|
|
|
|
|
grViewport::~grViewport()
|
|
{
|
|
ASSERT(!vp_Locked); // Viewport shouldn't be locked here!
|
|
|
|
// text_Font.free();
|
|
}
|
|
|
|
|
|
void grViewport::set_clipping_rect(int left, int top, int right, int bottom)
|
|
{
|
|
ASSERT(!vp_Locked); // YOU CANT DO THIS WHILE LOCKED!
|
|
|
|
// these are local to the viewport.
|
|
// vp_Left = left;
|
|
// vp_Top = top;
|
|
// vp_Right = right;
|
|
// vp_Bottom = bottom;
|
|
}
|
|
|
|
|
|
// these functions set and restore the state of the viewport (font, colors, etc.)
|
|
void grViewport::get_state(tVPState *state)
|
|
{
|
|
state->font = text_Font;
|
|
state->text_spacing = text_Spacing;
|
|
state->text_line_spacing = text_Line_spacing;
|
|
get_char_properties(&state->chprops);
|
|
}
|
|
|
|
|
|
void grViewport::set_state(const tVPState *state)
|
|
{
|
|
set_char_properties(GR_VPCP_ALL, &state->chprops);
|
|
text_Font = state->font;
|
|
text_Spacing = state->text_spacing;
|
|
text_Line_spacing = state->text_line_spacing;
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// font functions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// bltting functions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void grViewport::clear(ddgr_color col) // clear with background color
|
|
{
|
|
sf_Parent->clear(CLIP_LEFT, CLIP_TOP, (vp_Right-vp_Left)+1, (vp_Bottom-vp_Top)+1,col);
|
|
}
|
|
|
|
|
|
void grViewport::blt(int dx, int dy, grSurface *ssf)
|
|
{
|
|
int x1,y1,x2,y2, sx, sy;
|
|
|
|
// perform rectangular clipping
|
|
x1 = global_x(dx); y1 = global_y(dy);
|
|
x2 = x1+ssf->width()-1; y2 = y1+ssf->height()-1;
|
|
|
|
if (x1 < CLIP_LEFT) sx = CLIP_LEFT - x1;
|
|
else sx = 0;
|
|
if (y1 < CLIP_TOP) sy = CLIP_TOP - y1;
|
|
else sy = 0;
|
|
|
|
if (clip_rect(x1, y1, x2, y2)==2) return;
|
|
|
|
sf_Parent->blt(x1, y1, ssf, sx, sy, x2-x1+1, y2-y1+1);
|
|
}
|
|
|
|
|
|
void grViewport::blt(int dx, int dy, grSurface *ssf, int sx, int sy, int sw, int sh)
|
|
{
|
|
int x1, y1, x2, y2;
|
|
|
|
x1 = global_x(dx); y1 = global_y(dy); x2 = x1+sw-1; y2 = y1+sh-1;
|
|
if (clip_rect(x1, y1, x2, y2)==2) return;
|
|
|
|
sf_Parent->blt(x1, y1, ssf, sx, sy, x2-x1+1, y2-y1+1);
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// general lock creation functions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
grSurface* grViewport::lock()
|
|
{
|
|
int rowsize;
|
|
|
|
ASSERT(!vp_Locked);
|
|
|
|
sf_Parent->lock(CLIP_LEFT, CLIP_TOP, &rowsize);
|
|
vp_Locked = 1;
|
|
|
|
if (vp_Locked) {
|
|
pen_Obj.sf = &sf_Parent->ddsfObj;
|
|
pen_Obj.rowsize = sf_Parent->rowsize();
|
|
pen_Obj.rgbcolor = GR_RGB(255,255,255);
|
|
|
|
// SUPERHACK. Pen functions don't use the adjusted pointer of grSurface, but use the
|
|
// base data pointer provided by locking the entire surface at (0,0). Pen functions
|
|
// use global coordinates, so they can calculate the adjusted pointer themselves. This
|
|
// makes global_x and global_y consisitent with the surface base pointer. This problem
|
|
// was caused by the clipping rect being a virtual viewport within a viewport to make
|
|
// the 3d system work better.
|
|
pen_Obj.data = sf_Parent->m_OrigDataPtr;
|
|
}
|
|
|
|
grViewport::vp_Current_VP = this;
|
|
|
|
return sf_Parent;
|
|
}
|
|
|
|
|
|
void grViewport::unlock()
|
|
{
|
|
ASSERT(vp_Locked);
|
|
|
|
sf_Parent->unlock();
|
|
vp_Locked = 0;
|
|
|
|
grViewport::vp_Current_VP = NULL;
|
|
|
|
pen_Obj.data = NULL;
|
|
pen_Obj.rowsize = 0;
|
|
pen_Obj.sf = NULL;
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// miscellaneous viewport functions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void grViewport::setpixel(ddgr_color col, int x, int y)
|
|
{
|
|
ASSERT(vp_Locked);
|
|
|
|
rend_SetPixel(col, x,y);
|
|
}
|
|
|
|
|
|
void grViewport::setpixelc(ddgr_color col, int x, int y)
|
|
{
|
|
ASSERT(vp_Locked);
|
|
|
|
if (x < CLIP_LEFT || x > CLIP_RIGHT || y < CLIP_TOP || y > CLIP_BOTTOM) return;
|
|
|
|
rend_SetPixel(col, x,y);
|
|
}
|
|
|
|
|
|
|
|
ddgr_color grViewport::getpixel(int x, int y)
|
|
{
|
|
ASSERT(vp_Locked);
|
|
|
|
return rend_GetPixel(x,y);
|
|
}
|
|
|
|
|
|
ddgr_color grViewport::getpixelc(int x, int y)
|
|
{
|
|
ASSERT(vp_Locked);
|
|
|
|
if (x < CLIP_LEFT || x > CLIP_RIGHT || y < CLIP_TOP || y > CLIP_BOTTOM) return 0;
|
|
|
|
return rend_GetPixel(x,y);
|
|
}
|
|
|
|
|
|
void grViewport::lock_clear(ddgr_color col)
|
|
{
|
|
int l=CLIP_LEFT,t = CLIP_TOP,r=CLIP_RIGHT, b=CLIP_BOTTOM;
|
|
ddgr_surface *memsurf = sf_Parent->scratch_mem_surf;
|
|
|
|
ASSERT(vp_Locked);
|
|
|
|
if (sf_Parent->ddsfObj.flags & SURFFLAG_RENDERER) {
|
|
rend_FillRect(col, l,t,r,b);
|
|
}
|
|
else {
|
|
memsurf->bpp = pen_Obj.sf->bpp;
|
|
|
|
gr_mem_surf_Init(memsurf, pen_Obj.data, pen_Obj.rowsize);
|
|
gr_mem_surf_Clear(memsurf, col, l,t,r-l+1,b-t+1);
|
|
}
|
|
}
|
|
|
|
|
|
void grViewport::lock_clear(ddgr_color col, int l, int t, int r, int b)
|
|
{
|
|
ddgr_surface *memsurf = sf_Parent->scratch_mem_surf;
|
|
|
|
ASSERT(vp_Locked);
|
|
|
|
l = global_x(l);
|
|
t = global_y(t);
|
|
r = global_x(r);
|
|
b = global_y(b);
|
|
|
|
clip_rect(l,t,r,b);
|
|
|
|
if (sf_Parent->ddsfObj.flags & SURFFLAG_RENDERER) {
|
|
rend_FillRect(col, l,t,r,b);
|
|
}
|
|
else {
|
|
memsurf->bpp = pen_Obj.sf->bpp;
|
|
gr_mem_surf_Init(memsurf, pen_Obj.data, pen_Obj.rowsize);
|
|
gr_mem_surf_Clear(memsurf, col, l,t,r-l+1,b-t+1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// private functions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// grPen::clip_rect
|
|
// returns 2 if totally clipped
|
|
// returns 1 if partially clipped
|
|
// returns 0 if not clipped.
|
|
|
|
int grViewport::clip_rect(int &l, int &t, int &r, int &b)
|
|
{
|
|
int clipped = 0;
|
|
|
|
if (l > r) SWAP(l,r);
|
|
if (t > b) SWAP(t,b);
|
|
|
|
if (l > CLIP_RIGHT || t > CLIP_BOTTOM || r < CLIP_LEFT || b < CLIP_TOP) return 2;
|
|
|
|
if (l < CLIP_LEFT) { l = CLIP_LEFT; clipped = 1; }
|
|
if (t < CLIP_TOP) { t = CLIP_TOP; clipped = 1; }
|
|
if (r > CLIP_RIGHT) { r = CLIP_RIGHT; clipped = 1; }
|
|
if (b > CLIP_BOTTOM) { b = CLIP_BOTTOM; clipped = 1; }
|
|
|
|
return clipped;
|
|
}
|
|
|