mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
567 lines
18 KiB
C++
567 lines
18 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $Logfile: /DescentIII/Main/Lib/gr.h $
|
|
* $Revision: 18 $
|
|
* $Date: 4/17/99 6:15p $
|
|
* $Author: Samir $
|
|
*
|
|
* the 2d lib main header
|
|
*
|
|
* $Log: /DescentIII/Main/Lib/gr.h $
|
|
*
|
|
* 18 4/17/99 6:15p Samir
|
|
* replaced gr.h with grdefs.h and fixed resulting compile bugs.
|
|
*
|
|
* 17 4/14/99 3:59a Jeff
|
|
* fixed case mismatches in #includes
|
|
*
|
|
* 16 11/30/98 5:50p Jason
|
|
* added 4444 bitmap support
|
|
*
|
|
* 15 12/29/97 5:50p Samir
|
|
* Moved GR_COLOR_CHAR to grdefs.h from gr.h.
|
|
*
|
|
* 14 12/22/97 7:39p Samir
|
|
* Moved color constants from gr.h to grdefs.h
|
|
*
|
|
* 13 12/22/97 7:13p Samir
|
|
* Moved constants to grdefs.h
|
|
*
|
|
* 12 12/19/97 12:33p Samir
|
|
* Added alpha for text and took out abilitiy to create viewports inside
|
|
* viewports.
|
|
*
|
|
* 11 12/12/97 6:40p Samir
|
|
* Some viewport font functions.
|
|
*
|
|
* 10 11/16/97 6:54p Samir
|
|
* Added font::get_name function.
|
|
*
|
|
* 9 11/16/97 2:20p Samir
|
|
* Added macro to draw a bitmap to a viewport.
|
|
*
|
|
* 8 11/11/97 1:27p Samir
|
|
* Added functions to set text alpha values.
|
|
*
|
|
* 7 11/04/97 4:57p Samir
|
|
* Added get_text_color.
|
|
*
|
|
* 6 10/13/97 3:56p Jason
|
|
* made a better 3d bitmap system
|
|
*
|
|
* 5 10/03/97 11:59a Samir
|
|
* Added some color constants.
|
|
*
|
|
* 4 9/19/97 5:37p Samir
|
|
* Software font coloring works.
|
|
*
|
|
* 1 6/23/97 9:25p Samir
|
|
* added because source safe sucks
|
|
*
|
|
* 39 6/16/97 3:01p Samir
|
|
* Changed font system to work better with renderer. Fonts are rendered
|
|
* on bitmaps of 128x128 at load time.
|
|
*
|
|
* 38 6/12/97 6:30p Samir
|
|
* DDGR v2.0 Changes in 2d system implemented.
|
|
*
|
|
* 37 6/09/97 3:47p Jason
|
|
* fixed some color mapping problems
|
|
*
|
|
* 36 5/21/97 3:39p Jason
|
|
* added terrain editing stuff
|
|
*
|
|
* 35 5/21/97 1:08p Samir
|
|
* added conversion from 565 to ddgr_color format.
|
|
*
|
|
* 34 5/15/97 2:08p Samir
|
|
* Added grSurface::get_surface_desc and grViewport::get_parent.
|
|
*
|
|
* 33 5/13/97 6:36p Samir
|
|
* added lock_clear functions.
|
|
*
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#ifndef _GR_H
|
|
#define _GR_H
|
|
|
|
#include "Ddgr.h"
|
|
#include "fix.h"
|
|
#include "pserror.h"
|
|
|
|
class grMemorySurface;
|
|
class grViewport;
|
|
class grSurface;
|
|
class grPen;
|
|
|
|
// a 'pen' structure used by the 2d system to draw things.
|
|
struct gr_pen {
|
|
char *data;
|
|
int rowsize;
|
|
ddgr_color rgbcolor;
|
|
ddgr_color color;
|
|
ddgr_surface *sf;
|
|
};
|
|
|
|
enum grTextAlign { // used to align text along viewport
|
|
grTextUnjustified,
|
|
grTextLeft,
|
|
grTextCentered,
|
|
grTextRight,
|
|
grTextWordWrap
|
|
};
|
|
|
|
struct tCharProperties {
|
|
uint8_t alpha;
|
|
ddgr_color col[4];
|
|
};
|
|
|
|
#define GR_VPCP_ALPHA 1 // alpha value is valid in CharProperties
|
|
#define GR_VPCP_COLOR 2 // color values are valid in CharProperties.
|
|
#define GR_VPCP_ALL (1 + 2)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// class grFont
|
|
// will load and manage a font's capabilities.
|
|
// all fonts are stored in a 16bit hicolor format, or bitmasked.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
const int MAX_FONTS = 16, MAX_FONT_BITMAPS = 12;
|
|
|
|
#define DEFAULT_FONT 0
|
|
|
|
struct gr_font_file_record {
|
|
int16_t width, height; // width of widest character and height of longest char
|
|
int16_t flags; // flags used by the character renderer
|
|
int16_t baseline; // pixels given to lowercase below script line start at baseline
|
|
uint8_t min_ascii; // minimum ascii value used by font
|
|
uint8_t max_ascii; // max ascii value used by the font
|
|
int16_t byte_width; // width of a character in the font in bytes
|
|
uint8_t *raw_data; // pixel, map data.
|
|
uint8_t **char_data; // pointers to each character
|
|
int16_t *char_widths; // individual pixel widths of each character
|
|
uint8_t *kern_data; // kerning information for specific letter combos
|
|
};
|
|
|
|
struct gr_font_record {
|
|
char name[32];
|
|
char filename[32]; // filename of font
|
|
int references; // number of references of that font
|
|
int bmps[MAX_FONT_BITMAPS]; // font bitmap handles
|
|
grMemorySurface *surfs[MAX_FONT_BITMAPS];
|
|
uint8_t *ch_u, *ch_v, *ch_w, *ch_h, *ch_surf;
|
|
float *ch_uf, *ch_vf, *ch_wf, *ch_hf;
|
|
gr_font_file_record font;
|
|
|
|
};
|
|
|
|
class grFont {
|
|
static gr_font_record m_FontList[MAX_FONTS];
|
|
static grMemorySurface *m_CharSurf;
|
|
|
|
int m_FontHandle; // offset into m_FontList
|
|
|
|
public:
|
|
grFont();
|
|
~grFont();
|
|
grFont(const grFont &font) { m_FontHandle = font.m_FontHandle; };
|
|
|
|
const grFont &operator=(const grFont &font) {
|
|
m_FontHandle = font.m_FontHandle;
|
|
return *this;
|
|
};
|
|
|
|
public: // Manipulation functions
|
|
static void init_system();
|
|
static void close_system();
|
|
static int register_font(char *fontname, char *filename);
|
|
|
|
void init(const char *fontname);
|
|
void free();
|
|
|
|
// draw_char returns the next x value taking spacing and kerning into consideration.
|
|
int draw_char(grSurface *sf, int x, int y, int ch, tCharProperties *chprop);
|
|
int draw_char(grSurface *sf, int x, int y, int ch, int sx, int sy, int sw, int sh, tCharProperties *chprop);
|
|
|
|
private:
|
|
static void free_font(gr_font_record *ft);
|
|
|
|
static void load(char *filename, int slot);
|
|
static void translate_to_surfaces(int slot);
|
|
static void translate_mono_char(grSurface *sf, int x, int y, int index, gr_font_file_record *ft, int width);
|
|
|
|
uint8_t *get_kern_info(uint8_t c1, uint8_t c2);
|
|
void charblt16(grSurface *dsf, ddgr_color col, int dx, int dy, grSurface *ssf, int sx, int sy, int sw, int sh);
|
|
|
|
public: // Accessor functions
|
|
char *get_name() const {
|
|
if (m_FontHandle == -1)
|
|
return NULL;
|
|
else
|
|
return m_FontList[m_FontHandle].name;
|
|
};
|
|
int min_ascii() const {
|
|
ASSERT(m_FontHandle > -1);
|
|
return m_FontList[m_FontHandle].font.min_ascii;
|
|
};
|
|
int max_ascii() const {
|
|
ASSERT(m_FontHandle > -1);
|
|
return m_FontList[m_FontHandle].font.max_ascii;
|
|
};
|
|
int height() const {
|
|
ASSERT(m_FontHandle > -1);
|
|
return m_FontList[m_FontHandle].font.height;
|
|
};
|
|
int get_char_info(int ch, int *width);
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// class grSurface
|
|
// contains a ddgr_bitmap object and allows for blting
|
|
// ----------------------------------------------------------------------------
|
|
|
|
struct ddgr_surface_node {
|
|
ddgr_surface *sf;
|
|
ddgr_surface_node *prev;
|
|
};
|
|
|
|
const int SURFTYPE_MEMORY = 256;
|
|
|
|
const int SURFFLAG_RENDERER = 256; // SURFACE will use renderer functions.
|
|
|
|
class grSurface {
|
|
public:
|
|
static void init_system(); // initializes some global stuff for surface system
|
|
static void close_system();
|
|
|
|
private:
|
|
friend class grViewport;
|
|
int surf_Locked; // same value for all grViewport objects
|
|
int m_SurfInit; // surface initialized
|
|
char *m_OrigDataPtr; // non-adjusted data pointer
|
|
char *m_DataPtr; // adjusted data pointer
|
|
int m_DataRowsize; // Data rowsize
|
|
|
|
static ddgr_surface_node *surf_list; // the surface list
|
|
static ddgr_surface_node *surf_list_cur; // current node on list.
|
|
static ddgr_surface *scratch_mem_surf; // use as temporary memory surface
|
|
|
|
private:
|
|
// coversion blts.
|
|
void xlat8_16(char *data, int w, int h, char *pal);
|
|
void xlat16_16(char *data, int w, int h, int format = 0);
|
|
void xlat16_24(char *data, int w, int h);
|
|
void xlat24_16(char *data, int w, int h);
|
|
void xlat32_16(char *data, int w, int h);
|
|
|
|
void uniblt(int dx, int dy, grSurface *ssf, int sx, int sy, int sw, int sh);
|
|
|
|
protected:
|
|
ddgr_surface ddsfObj; // Used to call ddgr_surf_ functions
|
|
|
|
protected:
|
|
void add_to_list(ddgr_surface *sf); // used for surface heap management
|
|
void remove_from_list(ddgr_surface *sf);
|
|
|
|
int surf_init() const { return m_SurfInit; };
|
|
void surf_init(int init) { m_SurfInit = init; };
|
|
|
|
public:
|
|
grSurface();
|
|
virtual ~grSurface();
|
|
|
|
// creates a surface, allocates memory based off of parameters.
|
|
grSurface(int w, int h, int bpp, unsigned type, unsigned flags = 0, const char *name = NULL);
|
|
|
|
public:
|
|
unsigned get_flags() const { return ddsfObj.flags; };
|
|
|
|
void create(int w, int h, int bpp, unsigned type, unsigned flags = 0, const char *name = NULL);
|
|
|
|
void load(char *data, int w, int h, int bpp, int format = 0);
|
|
void load(int handle);
|
|
void load(char *data, int w, int h, char *pal);
|
|
void load(int handle, char *pal);
|
|
|
|
void free(); // non-dynamic version
|
|
|
|
int width() const {
|
|
ASSERT(m_SurfInit);
|
|
return ddsfObj.w;
|
|
};
|
|
int height() const {
|
|
ASSERT(m_SurfInit);
|
|
return ddsfObj.h;
|
|
};
|
|
int bpp() const {
|
|
ASSERT(m_SurfInit);
|
|
return ddsfObj.bpp;
|
|
};
|
|
unsigned flags() const {
|
|
ASSERT(m_SurfInit);
|
|
return ddsfObj.flags;
|
|
};
|
|
|
|
int rowsize() const {
|
|
ASSERT(m_SurfInit);
|
|
return m_DataRowsize;
|
|
};
|
|
char *data() const {
|
|
ASSERT(m_SurfInit);
|
|
return m_DataPtr;
|
|
};
|
|
|
|
void clear(ddgr_color col = 0);
|
|
void clear(int l, int t, int w, int h, ddgr_color col = 0);
|
|
void replace_color(ddgr_color sc, ddgr_color dc);
|
|
|
|
void blt(int dx, int dy, grSurface *ssf);
|
|
void blt(int dx, int dy, grSurface *ssf, int sx, int sy, int sw, int sh);
|
|
|
|
char *lock(int *rowsize);
|
|
char *lock(int x, int y, int *rowsize);
|
|
void unlock();
|
|
|
|
void get_surface_desc(ddgr_surface *surf) { *surf = ddsfObj; };
|
|
|
|
// This is VERY system dependent when called, sorry but I think this may be necessary
|
|
void attach_to_window(unsigned handle);
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// class grMemorySurface
|
|
// this is a software bitmap not video driver dependant
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class grMemorySurface final : public grSurface {
|
|
bool m_FirstTimeInit; // do special stuff if we are initializing for first time
|
|
bool m_AllowInit; // we only allow initialization if we didn't create it.
|
|
|
|
public:
|
|
grMemorySurface();
|
|
virtual ~grMemorySurface();
|
|
|
|
// allocates a surface from system memory (quicker version of grSurface)
|
|
grMemorySurface(int w, int h, int bpp, unsigned flags = 0, const char *name = NULL);
|
|
|
|
// initializes a surface using a bitmap handle (no allocation)
|
|
grMemorySurface(int bm);
|
|
|
|
// inititalizes a surface using raw data,width,rowsize info information.
|
|
bool init(int w, int h, int bpp, char *data, int rowsize, unsigned flags = 0, const char *name = NULL);
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// class grHardwareSurface
|
|
// this is a hardware bitmap allocated from the video driver
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class grHardwareSurface final : public grSurface {
|
|
public:
|
|
grHardwareSurface() = default;
|
|
grHardwareSurface(int w, int h, int bpp, unsigned flags = 0, const char *name = NULL);
|
|
virtual ~grHardwareSurface() = default;
|
|
|
|
bool create(int w, int h, int bpp, unsigned flags = 0, const char *name = NULL);
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// class grScreen
|
|
// child class of grSurface. Handles initializing the screen, and
|
|
// is used by the grViewport class to draw onto the screen
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class grScreen final : public grSurface {
|
|
friend class grViewport;
|
|
|
|
public:
|
|
grScreen(int w, int h, int bpp, const char *name = NULL);
|
|
virtual ~grScreen() = default;
|
|
|
|
void flip();
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// class grViewport
|
|
// a viewport is a bounded rectangle on either a screen or bitmap.
|
|
// one should be able to draw any 2d object on a viewport region.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// contains state information for a viewport.
|
|
struct tVPState {
|
|
grFont font;
|
|
int text_spacing;
|
|
int text_line_spacing;
|
|
tCharProperties chprops;
|
|
};
|
|
|
|
class grViewport {
|
|
static int vp_Locked; // tells us if any viewport is locked
|
|
static grViewport *vp_Current_VP; // current locked viewport
|
|
|
|
grFont text_Font;
|
|
int text_Spacing;
|
|
int text_Line_spacing;
|
|
tCharProperties char_Props;
|
|
|
|
private:
|
|
void draw_text_line(int x, int y, char *str);
|
|
void draw_text_line_clip(int x, int y, char *str);
|
|
int clip_rect(int &x1, int &y1, int &x2, int &y2);
|
|
|
|
protected:
|
|
int vp_Left, vp_Top, vp_Right, // viewport's global screen/bitmap bounds
|
|
vp_Bottom;
|
|
|
|
int vp_InitLeft, vp_InitTop, vp_InitRight, vp_InitBottom; // viewport's initial global screen coords
|
|
|
|
grSurface *sf_Parent; // bitmap where viewport points to
|
|
gr_pen pen_Obj;
|
|
|
|
public:
|
|
grViewport(grScreen *scr_parent);
|
|
grViewport(grSurface *sf_parent);
|
|
~grViewport();
|
|
|
|
grSurface *get_parent() const { return sf_Parent; };
|
|
|
|
// these are the viewport's initial bounds with respect to parent surface
|
|
// these can't be changed.
|
|
int width() const { return (vp_InitRight - vp_InitLeft) + 1; };
|
|
int height() const { return (vp_InitBottom - vp_InitTop) + 1; };
|
|
int left() const { return vp_InitLeft; };
|
|
int top() const { return vp_InitTop; };
|
|
int right() const { return vp_InitRight; };
|
|
int bottom() const { return vp_InitBottom; };
|
|
|
|
// these clipping coordinates are local to the viewports initial rectangle, based off
|
|
// of parent surface. All 2d functions use these coords to base their drawing.
|
|
// If we draw at (0,0) and the clip region is at (80,90,200,160) then we will draw at 80,90.
|
|
int clip_width() const { return (vp_Right - vp_Left) + 1; };
|
|
int clip_height() const { return (vp_Bottom - vp_Top) + 1; };
|
|
int clip_left() const { return vp_Left; };
|
|
int clip_top() const { return vp_Top; };
|
|
int clip_right() const { return vp_Right; };
|
|
int clip_bottom() const { return vp_Bottom; };
|
|
void set_clipping_rect(int left, int top, int right, int bottom);
|
|
|
|
// these convert local viewport coords to global screen/surface coords
|
|
int global_x(int lx) const { return vp_InitLeft + vp_Left + lx; };
|
|
int global_y(int ly) const { return vp_InitTop + vp_Top + ly; };
|
|
int local_x(int gx) const { return gx - vp_Left - vp_InitLeft; };
|
|
int local_y(int gy) const { return gy - vp_Top - vp_InitTop; };
|
|
|
|
// these functions set and restore the state of the viewport (font, colors, etc.)
|
|
void get_state(tVPState *state);
|
|
void set_state(const tVPState *state);
|
|
|
|
// bltting functions on viewport
|
|
void clear(ddgr_color col = 0); // clear with background color
|
|
void lock_clear(ddgr_color col = 0); // software clear. must be used in lock
|
|
void lock_clear(ddgr_color col, int l, int t, int w, int h);
|
|
void blt(int dx, int dy, grSurface *ssf);
|
|
void blt(int dx, int dy, grSurface *ssf, int sx, int sy, int sw, int sh);
|
|
|
|
public:
|
|
grSurface *lock(); // lock and
|
|
void unlock(); // unlock (implicitly locks surface)
|
|
|
|
// these functions only work on locked surfaces.
|
|
void hline(ddgr_color, int x1, int x2, int y1);
|
|
void line(ddgr_color color, int x1, int y1, int x2, int y2);
|
|
void rect(ddgr_color color, int l, int t, int r, int b);
|
|
void fillrect(ddgr_color color, int l, int t, int r, int b);
|
|
void setpixel(ddgr_color col, int x, int y);
|
|
void setpixelc(ddgr_color col, int x, int y);
|
|
ddgr_color getpixel(int x, int y);
|
|
ddgr_color getpixelc(int x, int y);
|
|
void circle(ddgr_color col, int xc, int yc, int r);
|
|
void fillcircle(ddgr_color col, int xc, int yc, int r);
|
|
// end
|
|
|
|
public:
|
|
// These functions only work on locked surfaces
|
|
int printf(grTextAlign align, int x, int y, char *fmt, ...);
|
|
int printf(int x, int y, char *fmt, ...);
|
|
int puts(grTextAlign align, int x, int y, char *str);
|
|
int puts(int x, int y, char *str);
|
|
|
|
// text formatting functions
|
|
public:
|
|
int get_text_line_width(char *text);
|
|
void set_font(const char *fontname);
|
|
void get_font(char *fontname, int size);
|
|
int get_current_font_height() const { return text_Font.height(); };
|
|
int get_text_spacing() const { return text_Spacing; };
|
|
int get_text_line_spacing() const { return text_Line_spacing; };
|
|
void set_text_spacing(int spacing) { text_Spacing = spacing; };
|
|
void set_text_line_spacing(int spacing) { text_Line_spacing = spacing; };
|
|
|
|
// visual properties of text functions
|
|
public:
|
|
void set_text_color(ddgr_color color);
|
|
ddgr_color get_text_color() const;
|
|
void set_char_properties(unsigned flags, const tCharProperties *props);
|
|
void get_char_properties(tCharProperties *props) const;
|
|
// end
|
|
};
|
|
|
|
// inline definitions for grViewport functions
|
|
|
|
inline void grViewport::set_text_color(ddgr_color color) {
|
|
char_Props.col[0] = color;
|
|
char_Props.col[1] = color;
|
|
char_Props.col[2] = color;
|
|
char_Props.col[3] = color;
|
|
}
|
|
|
|
inline ddgr_color grViewport::get_text_color() const { return char_Props.col[0]; }
|
|
|
|
inline void grViewport::set_char_properties(unsigned flags, const tCharProperties *props) {
|
|
if (flags & GR_VPCP_COLOR) {
|
|
char_Props.col[0] = props->col[0];
|
|
char_Props.col[1] = props->col[1];
|
|
char_Props.col[2] = props->col[2];
|
|
char_Props.col[3] = props->col[3];
|
|
}
|
|
if (flags & GR_VPCP_ALPHA) {
|
|
char_Props.alpha = props->alpha;
|
|
}
|
|
}
|
|
|
|
inline void grViewport::get_char_properties(tCharProperties *props) const {
|
|
props->col[0] = char_Props.col[0];
|
|
props->col[1] = char_Props.col[1];
|
|
props->col[2] = char_Props.col[2];
|
|
props->col[3] = char_Props.col[3];
|
|
props->alpha = char_Props.alpha;
|
|
}
|
|
|
|
// useful macros
|
|
|
|
static inline void VP_BITBLT(grViewport *vp, int dx, int dy, int bm) {
|
|
grMemorySurface surf(bm);
|
|
vp->blt(dx, dy, &surf);
|
|
}
|
|
|
|
#endif
|