Vendor the Shockolate engine and build it via a Docker image with every
build / build (push) Failing after 5s

dependency (SDL2, SDL2_mixer, fluidsynth-lite, a MIDI soundfont)
prebuilt, so compiling the engine needs no network access - just the
image and the engine source. Add res/assets/extract_assets.sh to pull
the game's data files out of a purchased GOG installer, and a Makefile
that assembles a runnable dist/ from the two.

Also add `make package`, which builds a redistributable tarball that
omits the proprietary game assets (shipping res/GET_ASSETS.txt instead)
plus license information for both the MIT tooling and the GPLv3 engine,
and a Gitea Actions workflow that builds and publishes it to
dl.ladkau.de on every push.
This commit is contained in:
ml
2026-07-19 15:43:38 +02:00
parent 3ed6400466
commit a5ec8db5f7
826 changed files with 214554 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,87 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/rcs/clip.h $
* $Revision: 1.11 $
* $Author: kaboom $
* $Date: 1993/09/02 19:41:01 $
*
* Prototypes for 2d clippers, constants for clipping codes.
*
* $Log: clip.h $
* Revision 1.11 1993/09/02 19:41:01 kaboom
* Added prototype for 24-bit bitmap clipper.
*
* Revision 1.10 1993/08/10 18:48:49 kaboom
* Added prototype for gr_clip_spoly.
*
* Revision 1.9 1993/02/22 14:32:46 kaboom
* Changed name of gr_clip_int_rect() to gr_clip_rect(). Removed the
* prototypes for gr_clip_fix_rect() and gr_clip_int_poly().
*
* Revision 1.8 1993/02/19 13:12:04 jaemz
* Added definition for cpoly clipper
*
* Revision 1.7 1993/02/04 17:09:02 kaboom
* Fixed bug in prototype for gr_clip_fix_rect. Moved clip code defines
* to here.
*
* Revision 1.6 1993/01/14 18:30:46 kaboom
* Added prototype for gr_clip_fix_poly(). Changed clip_xxx to gr_clip_xxx.
*
* Revision 1.5 1993/01/12 00:03:07 kaboom
* Added prototype for clip_int_poly().
*
* Revision 1.4 1992/11/12 13:46:58 kaboom
* Changed flat8 bitmap clipper to not allocate a new bitmap; now it changes the
* bitmap passed in and returns the clip code. Added prototype for monochrome
* bitmap clipper.
*
* Revision 1.3 1992/10/21 16:02:32 kaboom
* Updates references to gr_xxx structures to grs_xxx.
*
* Revision 1.2 1992/10/13 17:40:12 kaboom
* Added prototypes for clip_fix_line, clip_int_rect, clip_fix_rect, and also
* for clip_int_bitmap.
*
* Revision 1.1 1992/10/09 16:51:22 kaboom
* Initial revision
*/
#ifndef __CLIP_H
#define __CLIP_H
/* prototypes for analytic clippers. */
extern int gr_clip_int_line (short *x0, short *y0, short *x1, short *y1);
extern int gr_clip_fix_line (long *x0, long *y0, long *x1, long *y1);
extern int gr_clip_fix_poly (int n, fix *vlist, fix *clist);
extern int gr_clip_spoly (int n, fix *vlist, fix *clist, fix *ilist, fix *cilist);
extern int gr_clip_fix_cpoly (int n, fix *vlist, grs_rgb *blist, fix *clist, grs_rgb *cblist);
extern int gr_clip_rect (short *left, short *top, short *right, short *bot);
extern int gr_clip_mono_bitmap (grs_bitmap *bm, short *x, short *y);
extern int gr_clip_flat8_bitmap (grs_bitmap *bm, short *x, short *y);
extern int gr_clip_flat24_bitmap (grs_bitmap *bm, short *x, short *y);
/* clip codes. */
#define CLIP_NONE 0
#define CLIP_LEFT 1
#define CLIP_TOP 2
#define CLIP_RIGHT 4
#define CLIP_BOT 8
#define CLIP_ALL 16
#endif /* !__CLIP_H */
@@ -0,0 +1,104 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clpclin.c $
* $Revision: 1.2 $
* $Author: lmfeeney $
* $Date: 1994/06/11 01:14:47 $
*/
/* clip and fill colored line -- using line fill table and grs_vertex interfaces.
These will be the preferred interfaces and are called from the original
gr_xxx canvas table x,y routines.
*/
#include <stdlib.h>
#include "clpcon.h"
#include "clpfcn.h"
#include "grrend.h"
#include "rgb.h"
#include "scrdat.h"
#include "clpltab.h"
#include "lg.h"
#define fix_make_nof(x) fix_make(x,0x0000)
/* The amount of copying into and out of vertex's is quite
disgusting.
Also, becuase of the vertex interface, we've introduced a new
function call that we can't inline because it needs to return a
value.
*/
int gri_cline_clip (grs_vertex *v0, grs_vertex *v1)
{
int r;
fix x0, y0, x1, y1;
fix xb0, xb1, yb0, yb1;
uchar r0, g0, b0, r1, g1, b1;
fix dr, dg, db;
fix pixels, pixels_0, pixels_1;
/* transfer out of v0, v1 -- from old gen_clin */
x0 = v0->x; y0 = v0->y;
r0 = (uchar) (v0->u); g0 = (uchar) (v0->v); b0 = (uchar) (v0->w);
x1 = v1->x; y1 = v1->y;
r1 = (uchar) (v1->u); g1 = (uchar) (v1->v); b1 = (uchar) (v1->w);
xb0 = x0; xb1 = x1; yb0 = y0; yb1 = y1;
pixels = lg_max(fix_abs(y1-y0),fix_abs(x1-x0));
if (pixels != 0) {
dr = fix_div(fix_make_nof(r1-r0),pixels);
dg = fix_div(fix_make_nof(g1-g0),pixels);
db = fix_div(fix_make_nof(b1-b0),pixels);
}
r = gr_clip_fix_line (&x0, &y0, &x1, &y1);
if (r != CLIP_ALL) {
if (((r0 != r1) || (g0 != g1) || (b0 != b1)) &&
((x0 != xb0) || (y0 != yb0) || (x1 != xb1) || (y1 != yb1))) {
pixels_0 = lg_max(fix_abs(yb0-y0),fix_abs(xb0-x0)); /* # pixels lost */
pixels_1 = lg_max(fix_abs(yb1-y1),fix_abs(xb1-x1)); /* for endpoints */
r0 += fix_int(fix_mul(dr, pixels_0));
g0 += fix_int(fix_mul(dg, pixels_0));
b0 += fix_int(fix_mul(db, pixels_0));
r1 -= fix_int(fix_mul(dr, pixels_1));
g1 -= fix_int(fix_mul(dg, pixels_1));
b1 -= fix_int(fix_mul(db, pixels_1));
}
}
/* and transfer back to v0, v1 */
(v0->x) = x0; (v0->y) = y0;
(v0->u) = r0; (v0->v) = g0; (v0->w) = b0;
(v1->x) = x1; (v1->y) = y1;
(v1->u) = r1; (v1->v) = g1; (v1->w) = b1;
return r;
}
@@ -0,0 +1,45 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clpcon.h $
* $Revision: 1.1 $
* $Author: kaboom $
* $Date: 1993/10/01 15:32:22 $
*
* Clipping code constants.
*
* This file is part of the 2d library.
*
* $Log: clpcon.h $
* Revision 1.1 1993/10/01 15:32:22 kaboom
* Initial revision
*
*/
#ifndef __CLPCON
#define __CLPCON
/* clip codes. */
#define CLIP_NONE 0
#define CLIP_LEFT 1
#define CLIP_TOP 2
#define CLIP_RIGHT 4
#define CLIP_BOT 8
#define CLIP_ALL 16
#endif /* !__CLPCON */
@@ -0,0 +1,84 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clpf24.c $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:01 $
*
* Routines for clipping flat 24 bitmaps to a rectangle.
*
* This file is part of the 2d library.
*
* $Log: clpf24.c $
* Revision 1.3 1993/10/19 09:50:01 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/01 15:38:30 kaboom
* Cleaned up code some; converted to using clpcon.h instead of clip.h.
*
* Revision 1.1 1993/09/02 19:41:21 kaboom
* Initial revision
*/
#include "grs.h"
#include "cnvdat.h"
#include "clip.h"
int gr_clip_flat24_bitmap (grs_bitmap *bm, short *x, short *y)
{
int code = CLIP_NONE;
int extra;
int l, r, t, b;
l=*x; r=l+bm->w; t=*y; b=t+bm->h;
if (l>grd_clip.right || r<grd_clip.left ||
t>grd_clip.bot || b<grd_clip.top)
/* bitmap is completely clipped. */
return CLIP_ALL;
if (l < grd_clip.left) {
/* bitmap is off the left edge of the window. */
extra = grd_clip.left-l;
bm->w -= extra;
bm->bits += 3*extra;
*x = grd_clip.left;
code |= CLIP_LEFT;
}
if (r > grd_clip.right) {
/* off the right edge of the window. */
bm->w -= r-grd_clip.right;
code |= CLIP_RIGHT;
}
if (t < grd_clip.top) {
/* off the top of the window. */
extra = grd_clip.top-t;
bm->h -= extra;
bm->bits += bm->row*extra;
*y = grd_clip.top;
code |= CLIP_TOP;
}
if (b > grd_clip.bot) {
/* off the bottom of the window. */
bm->h -= b-grd_clip.bot;
code |= CLIP_BOT;
}
return code;
}
@@ -0,0 +1,70 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clpfcn.h $
* $Revision: 1.3 $
* $Author: lmfeeney $
* $Date: 1994/06/11 00:46:51 $
*
* Routines for clipping vertex pointer polygons to a rectangle.
*
* This file is part of the 2d library.
*
* $Log: clpfcn.h $
* Revision 1.3 1994/06/11 00:46:51 lmfeeney
* gr_clip_fix_code is now used in mulitple 2d files, but probably
* doesn't need to be external to 2d.h (oh, well)
*
* Revision 1.2 1993/10/19 09:59:01 kaboom
* Fixed #ifndef check macro, now includes grs.h.
*
* Revision 1.1 1993/10/01 15:34:00 kaboom
* Initial revision
*/
#ifndef __CLPFCN_H
#define __CLPFCN_H
#include "grs.h"
#include "plytyp.h"
/* prototypes for analytic clippers. */
extern int gr_clip_fix_code
(fix, fix);
extern int gr_clip_int_line
(short *x0, short *y0, short *x1, short *y1);
extern int gr_clip_fix_line
(fix *x0, fix *y0, fix *x1, fix *y1);
extern int gr_clip_fix_poly
(int n, fix *vlist, fix *clist);
extern int gr_clip_poly
(int n, int l, grs_vertex **vplist, grs_vertex ***pcplist);
extern int gr_clip_spoly
(int n, fix *vlist, fix *clist, fix *ilist, fix *cilist);
extern int gr_clip_fix_cpoly
(int n, fix *vlist, grs_rgb *blist, fix *clist, grs_rgb *cblist);
extern int gr_clip_rect
(short *left, short *top, short *right, short *bot);
extern int gr_clip_mono_bitmap
(grs_bitmap *bm, short *x, short *y);
extern int gr_clip_flat8_bitmap
(grs_bitmap *bm, short *x, short *y);
extern int gr_clip_flat24_bitmap
(grs_bitmap *bm, short *x, short *y);
#endif /* !__CLPFCN_H */
@@ -0,0 +1,131 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clplin.c $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:06 $
*
* Routines for clipping fixed-point lines to a rectangle.
*
* This file is part of the 2d library.
*
* $Log: clplin.c $
* Revision 1.4 1993/10/19 09:50:06 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/01 15:38:55 kaboom
* Cleaned up code some; converted to using clpcon.h instead of clip.h.
*
* Revision 1.2 1993/06/15 20:16:51 kaboom
* Fixed clipper to deal with padded clipping region.
*
* Revision 1.1 1993/02/22 14:41:22 kaboom
* Initial revision
*
********************************************************************
* Log from old clip.c:
*
* Revision 1.11 1993/02/05 16:27:54 matt
* 2. Added parens to gr_clip_fix_line to fix the case where both points were
* off screen.
* 3. Changed gr_clip_fix_line() to use new fix_mul_div() function.
*
* Revision 1.5 1992/11/12 13:31:58 kaboom
* Fixed bug in fixed-point line clipper which was causing hangs.
* Several of the clipping region values were being read as integers,
* not fixed-point numbers.
*/
#include "grs.h"
#include "clpcon.h"
#include "cnvdat.h"
/* Returns clip code for fixed-point coordinates for the Cohen-Sutherland
line clipper. */
int gr_clip_fix_code (fix x, fix y)
{
int code = 0;
if (x < grd_fix_clip.left)
code |= CLIP_LEFT;
else if (x > grd_fix_clip.right-fix_make(1,0))
code |= CLIP_RIGHT;
if (y < grd_fix_clip.top)
code |= CLIP_TOP;
else if (y > grd_fix_clip.bot-fix_make(1,0))
code |= CLIP_BOT;
return code;
}
/* fixed-point Cohen-Sutherland line clipper. */
int gr_clip_fix_line (fix *x0, fix *y0, fix *x1, fix *y1)
{
int code0; /* clip code for (x0,y0) */
int code1; /* code for (x1,y1) */
int code; /* code for current point */
fix dx; /* x distance */
fix dy; /* y distance */
fix *px; /* pointer to x current coordinate */
fix *py; /* " to current y */
dx = *x1-*x0;
dy = *y1-*y0;
while (1) {
/* get codes for endpoints. */
code0 = gr_clip_fix_code (*x0, *y0);
code1 = gr_clip_fix_code (*x1, *y1);
if (code0==0 && code1==0) /* check trivial accept */
return CLIP_NONE;
else if ((code0&code1) != 0) /* check for trivial reject */
return CLIP_ALL;
/* set current code and px&py. first, for point0, then when it's
dealt with, point1. */
if (code0 != 0) {
px = x0;
py = y0;
code = code0;
} else {
px = x1;
py = y1;
code = code1;
}
/* check for left/right clip; compute intersection. */
if (code & CLIP_LEFT) {
*py += fix_mul_div (dy, grd_fix_clip.left-*px, dx);
*px = grd_fix_clip.left;
} else if (code & CLIP_RIGHT) {
*py += fix_mul_div (dy, grd_fix_clip.right-fix_make(1,0)-*px, dx);
*px = grd_fix_clip.right-fix_make(1,0);
}
/* check for top/bottom clip; compute intersection. */
if (code & CLIP_TOP) {
*px += fix_mul_div (dx, grd_fix_clip.top-*py, dy);
*py = grd_fix_clip.top;
} else if (code & CLIP_BOT) {
*px += fix_mul_div (dx, grd_fix_clip.bot-fix_make(1,0)-*py, dy);
*py = grd_fix_clip.bot-fix_make(1,0);
}
}
}
@@ -0,0 +1,93 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clplin2.c $
* $Revision: 1.1 $
* $Author: lmfeeney $
* $Date: 1994/06/11 01:17:48 $
*/
#include <stdlib.h>
#include "grs.h"
#include "clpcon.h"
#include "clpfcn.h"
#include "grrect.h"
#include "clpltab.h"
/* The amount of copying into and out of vertex's is quite
disgusting.
Also, becuase of the vertex interface, we've introduced a new
function call that we can't inline because it needs to return a
value.
*/
int gri_line_clip (grs_vertex *v0, grs_vertex *v1)
{
int code0; /* clip code for (x0,y0) */
int code1; /* code for (x1,y1) */
int code; /* code for current point */
fix dx; /* x distance */
fix dy; /* y distance */
fix *px; /* pointer to x current coordinate */
fix *py; /* pointer to y current coordinate */
dx = v1->x - v0->x;
dy = v1->y - v0->y;
while (1) {
/* get codes for endpoints. */
code0 = gr_clip_fix_code (v0->x, v0->y);
code1 = gr_clip_fix_code (v1->x, v1->y);
if (code0==0 && code1==0) /* check trivial accept */
return CLIP_NONE;
else if ((code0&code1) != 0) /* check for trivial reject */
return CLIP_ALL;
/* set current code and px&py. first, for point0, then when it's
dealt with, point1. */
if (code0 != 0) {
px = &(v0->x);
py = &(v0->y);
code = code0;
} else {
px = &(v1->x);
py = &(v1->y);
code = code1;
}
/* check for left/right clip; compute intersection. */
if (code & CLIP_LEFT) {
*py += fix_mul_div (dy, grd_fix_clip.left-*px, dx);
*px = grd_fix_clip.left;
} else if (code & CLIP_RIGHT) {
*py += fix_mul_div (dy, grd_fix_clip.right-fix_make(1,0)-*px, dx);
*px = grd_fix_clip.right-fix_make(1,0);
}
/* check for top/bottom clip; compute intersection. */
if (code & CLIP_TOP) {
*px += fix_mul_div (dx, grd_fix_clip.top-*py, dy);
*py = grd_fix_clip.top;
} else if (code & CLIP_BOT) {
*px += fix_mul_div (dx, grd_fix_clip.bot-fix_make(1,0)-*py, dy);
*py = grd_fix_clip.bot-fix_make(1,0);
}
}
}
@@ -0,0 +1,44 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/clpltab.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/04 09:54:59 $
*/
#include "clpltyp.h"
#include "clpltab.h"
#include "grnull.h"
#include "line.h"
grt_line_clip_fill grd_line_clip_fill_table [GRD_LINE_TYPES] =
{
gri_line_clip_fill,
gri_iline_clip_fill,
gri_hline_clip_fill,
gri_vline_clip_fill,
gri_sline_clip_fill,
gri_cline_clip_fill,
gri_wire_poly_line_clip_fill,
gr_null,
gri_wire_poly_cline_clip_fill
};
grt_line_clip_fill * grd_line_clip_fill_vector = grd_line_clip_fill_table;
@@ -0,0 +1,69 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/clpltab.h $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/04 09:45:09 $
*/
/* External defintions for clipped line drawers and line clippers.
In general, there would be a table of clipped line drawers. Each
clipped line drawer would call the appropriate line clipper and
unclipped line drawer in whatever way it needed to for the kind of
clip.
NB: The vlin drawer can't easily call a clipper, since it is
compiled to be called from an interrupt. It inlines the routine.
The hlin drawer also inlines it's clipper, since the fn call
overhead is significant.
(A stecil clipped line drawer might interleave clip and unclipped
line draw calls, for example.)
*/
#ifndef __CLPLTAB_H
#define __CLPLTAB_H
#include "plytyp.h"
/* functions living in the vector */
extern int gri_line_clip_fill (long, long, grs_vertex *, grs_vertex *);
extern int gri_iline_clip_fill (long, long, grs_vertex *, grs_vertex *);
extern int gri_cline_clip_fill (long c, long parm, grs_vertex *v0, grs_vertex *v1);
extern int gri_sline_clip_fill (long c, long parm, grs_vertex *v0, grs_vertex *v1);
extern int gri_hline_clip_fill (short, short, short, long, long);
extern int gri_vline_clip_fill (short, short, short, long, long);
extern int gri_wire_poly_line_clip_fill (long c, long parm, grs_vertex *v0, grs_vertex *v1);
extern int gri_wire_poly_sline_clip_fill (long c, long parm, grs_vertex *v0, grs_vertex *v1);
extern int gri_wire_poly_cline_clip_fill (long c, long parm, grs_vertex *v0, grs_vertex *v1);
/* actual clippers */
extern int gri_line_clip (grs_vertex *, grs_vertex *);
extern int gri_cline_clip (grs_vertex *, grs_vertex *);
extern int gri_sline_clip (grs_vertex *, grs_vertex *);
/* these are implemented, but are not used */
extern int gri_hline_clip (short *, short *, short *);
extern int gri_vline_clip (short *, short *, short *);
#endif
@@ -0,0 +1,42 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clpltyp.h $
* $Revision: 1.1 $
* $Author: lmfeeney $
* $Date: 1994/06/11 01:10:35 $
*/
#ifndef __CLPLTYPE_H
#define __CLPLTYPE_H
#include "plytyp.h"
typedef
void *grt_line_clip_fill;
typedef
int (*grt_line_clip_fill_v) (long, long, grs_vertex *, grs_vertex *);
typedef
int (*grt_line_clip_fill_xy) (short, short, short, long, long);
extern grt_line_clip_fill *grd_line_clip_fill_vector;
#endif
@@ -0,0 +1,91 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clpmono.c $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:10 $
*
* Routines for clipping monochrome bitmaps to a rectangle.
*
* This file is part of the 2d library.
*
* $Log: clpmono.c $
* Revision 1.4 1993/10/19 09:50:10 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/01 15:38:56 kaboom
* Cleaned up code some; converted to using clpcon.h instead of clip.h.
*
* Revision 1.2 1993/05/17 13:45:11 kaboom
* Now handles padded clipping rectangle correctly.
*
* Revision 1.1 1993/02/22 14:41:36 kaboom
* Initial revision
*/
#include "grs.h"
#include "clpcon.h"
#include "cnvdat.h"
int gr_clip_mono_bitmap (grs_bitmap *bm, short *x, short *y)
{
int code = CLIP_NONE;
int extra;
int l, r, t, b;
l=*x; r=l+bm->w; t=*y; b=t+bm->h;
if (r<=grd_clip.left || l>=grd_clip.right ||
b<=grd_clip.top || t>=grd_clip.bot)
/* bitmap is completely clipped. */
return CLIP_ALL;
if (l < grd_clip.left) {
/* bitmap is off the left edge of the window. */
extra = grd_clip.left-l;
bm->w -= extra;
bm->bits += extra/8;
if ((bm->align+=extra%8) > 7) {
bm->align -= 8;
bm->bits++;
}
*x = grd_clip.left;
code |= CLIP_LEFT;
}
if (r > grd_clip.right) {
/* off the right edge of the window. */
bm->w -= *x+bm->w-grd_clip.right;
code |= CLIP_RIGHT;
}
if (t < grd_clip.top) {
/* off the top of the window. */
extra = grd_clip.top-t;
bm->h -= extra;
bm->bits += bm->row*extra;
*y = grd_clip.top;
code |= CLIP_TOP;
}
if (b > grd_clip.bot) {
/* off the bottom of the window. */
bm->h -= b-grd_clip.bot;
code |= CLIP_BOT;
}
return code;
}
@@ -0,0 +1,251 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/clpply.c $
* $Revision: 1.4 $
* $Author: kevin $
* $Date: 1994/08/10 01:32:39 $
*
* Routines for clipping a polygon to a rectangle.
*
* This file is part of the 2d library.
*
* $Log: clpply.c $
* Revision 1.4 1994/08/10 01:32:39 kevin
* fixed typo.
*
* Revision 1.3 1993/10/19 09:50:11 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/15 12:07:40 baf
* Removed reference to clip.h
*
* Revision 1.1 1993/10/01 15:40:46 kaboom
* Initial revision
*/
#include "grs.h"
#include "buffer.h"
#include "cnvdat.h"
#include "plytyp.h"
/* clips a polygon's screen coordinates and vertex parameters to the
current clipping rectangle. the polygon has n vertices, each with
l fixed-point values (including x,y), pointed to by vpl. the
destination buffer is returned in *pcplist. pass in *pcplist of NULL
to have it allocated.
note: this can be improved a lot. pointed should be coded for trivial
accept/reject. code can be saved in the enter/exit cases by noting
the change in the in/out status. */
int gr_clip_poly(int n, int l, grs_vertex **vpl, grs_vertex ***pcplist)
{
fix **cplist;
fix **tplist;
fix *tlist;
int i; /* source vertex index */
int j; /* destination vertex index */
int k;
int new_v = 0;
fix *v0, *v1;
fix num, den;
if (*pcplist)
cplist = (fix **)*pcplist;
else
cplist = (fix **)gr_alloc_temp(2*n*(l+2)*sizeof(fix *));
tplist = (fix **)(cplist+2*n);
tlist = (fix *)(tplist+2*n);
/* clip left edge from vpl->tplist */
v0 = ((fix **)vpl)[n-1];
for (i=j=0; i<n; i++) {
v1 = ((fix **)vpl)[i];
if (v0[0] >= grd_canvas->gc.clip.f.left) {
/* start point is inside half plane */
if (v1[0] >= grd_canvas->gc.clip.f.left)
/* both points inside half plane. output end point. */
tplist[j++] = v1;
else {
/* edge exits half plane. output intersection. */
num = grd_canvas->gc.clip.f.left-v0[0];
den = v1[0]-v0[0];
tlist[new_v] = grd_canvas->gc.clip.f.left;
tlist[new_v+1] = v0[1]+fix_mul_div(v1[1]-v0[1], num, den);
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
tplist[j++] = &tlist[new_v];
new_v += k;
}
} else {
/* start point is outside half plane. */
if (v1[0] >= grd_canvas->gc.clip.f.left) {
/* edge enters half plane. output intersection and end point. */
if (v1[0] != grd_canvas->gc.clip.f.left) {
num = grd_canvas->gc.clip.f.left-v0[0];
den = v1[0]-v0[0];
tlist[new_v] = grd_canvas->gc.clip.f.left;
tlist[new_v+1] = v0[1]+fix_mul_div(v1[1]-v0[1], num, den);
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
tplist[j++] = &tlist[new_v];
new_v += k;
}
tplist[j++] = v1;
} else
/* both points outside, eliminate edge. */
;
}
v0=v1;
}
/* clip top edge from tplist->cplist */
v0 = tplist[j-1];
for (n=j, i=j=0; i<n; i++) {
v1 = tplist[i];
if (v0[1] >= grd_canvas->gc.clip.f.top) {
/* start point is inside half plane */
if (v1[1] >= grd_canvas->gc.clip.f.top)
/* both points inside half plane. output end point. */
cplist[j++] = v1;
else {
/* edge exits half plane. output intersection. */
num = grd_canvas->gc.clip.f.top-v0[1];
den = v1[1]-v0[1];
tlist[new_v] = v0[0]+fix_mul_div(v1[0]-v0[0], num, den);
tlist[new_v+1] = grd_canvas->gc.clip.f.top;
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
cplist[j++] = &tlist[new_v];
new_v += k;
}
} else {
/* start point is outside half plane. */
if (v1[1] >= grd_canvas->gc.clip.f.top) {
/* edge enters half plane. output intersection and end point. */
if (v1[1] != grd_canvas->gc.clip.f.top) {
num = grd_canvas->gc.clip.f.top-v0[1];
den = v1[1]-v0[1];
tlist[new_v] = v0[0]+fix_mul_div(v1[0]-v0[0], num, den);
tlist[new_v+1] = grd_canvas->gc.clip.f.top;
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
cplist[j++] = &tlist[new_v];
new_v += k;
}
cplist[j++] = v1;
} else
/* both points outside, eliminate edge. */
;
}
v0=v1;
}
/* clip right edge from cplist->tplist */
v0 = cplist[j-1];
for (n=j, i=j=0; i<n; i++) {
v1 = cplist[i];
if (v0[0] <= grd_canvas->gc.clip.f.right) {
/* start point is inside half plane */
if (v1[0] <= grd_canvas->gc.clip.f.right)
/* both points inside half plane. output end point. */
tplist[j++] = v1;
else {
/* edge exits half plane. output intersection. */
num = grd_canvas->gc.clip.f.right-v0[0];
den = v1[0]-v0[0];
tlist[new_v] = grd_canvas->gc.clip.f.right;
tlist[new_v+1] = v0[1]+fix_mul_div(v1[1]-v0[1], num, den);
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
tplist[j++] = &tlist[new_v];
new_v += k;
}
} else {
/* start point is outside half plane. */
if (v1[0] <= grd_canvas->gc.clip.f.right) {
/* edge enters half plane. output intersection and end point. */
if (v1[0] != grd_canvas->gc.clip.f.right) {
num = grd_canvas->gc.clip.f.right-v0[0];
den = v1[0]-v0[0];
tlist[new_v] = grd_canvas->gc.clip.f.right;
tlist[new_v+1] = v0[1]+fix_mul_div(v1[1]-v0[1], num, den);
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
tplist[j++] = &tlist[new_v];
new_v += k;
}
tplist[j++] = v1;
} else
/* both points outside, eliminate edge. */
;
}
v0=v1;
}
/* clip bottom edge from tplist->cplist */
v0 = tplist[j-1];
for (n=j, i=j=0; i<n; i++) {
v1 = tplist[i];
if (v0[1] <= grd_canvas->gc.clip.f.bot) {
/* start point is inside half plane */
if (v1[1] <= grd_canvas->gc.clip.f.bot)
/* both points inside half plane. output end point. */
cplist[j++] = v1;
else {
/* edge exits half plane. output intersection. */
num = grd_canvas->gc.clip.f.bot-v0[1];
den = v1[1]-v0[1];
tlist[new_v] = v0[0]+fix_mul_div(v1[0]-v0[0], num, den);
tlist[new_v+1] = grd_canvas->gc.clip.f.bot;
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
cplist[j++] = &tlist[new_v];
new_v += k;
}
} else {
/* start point is outside half plane. */
if (v1[1] <= grd_canvas->gc.clip.f.bot) {
/* edge enters half plane. output intersection and end point. */
if (v1[1] != grd_canvas->gc.clip.f.bot) {
num = grd_canvas->gc.clip.f.bot-v0[1];
den = v1[1]-v0[1];
tlist[new_v] = v0[0]+fix_mul_div(v1[0]-v0[0], num, den);
tlist[new_v+1] = grd_canvas->gc.clip.f.bot;
for (k=2; k<l; k++)
tlist[new_v+k] = v0[k]+fix_mul_div(v1[k]-v0[k], num, den);
cplist[j++] = &tlist[new_v];
new_v += k;
}
cplist[j++] = v1;
} else
/* both points outside, eliminate edge. */
;
}
v0=v1;
}
*pcplist = (grs_vertex **)cplist;
/* return new number of vertices. */
return j;
}
@@ -0,0 +1,250 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clppoly.c $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:13 $
*
* Routines for clipping fixed-point polygons to a rectangle.
*
* This file is part of the 2d library.
*
* $Log: clppoly.c $
* Revision 1.4 1993/10/19 09:50:13 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/01 15:38:57 kaboom
* Cleaned up code some; converted to using clpcon.h instead of clip.h.
*
* Revision 1.2 1993/08/10 15:27:13 kaboom
* Reformatted function code.
*
* Revision 1.1 1993/02/22 14:41:42 kaboom
* Initial revision
*
********************************************************************
* Log from old clip.c:
*
* Revision 1.11 1993/02/05 16:27:54 matt
* Fixed gr_clip_fix_poly() and gr_clip_int_poly(), which got the
* arrays mixed up when clipping the top edge.
*
* Revision 1.8 1993/02/04 16:27:58 matt
* Fixed gr_clip_fix_poly() by using new fix_mul_div() function to
* preserve sign in computing new coordinates.
*/
#include "grs.h"
#include "buffer.h"
#include "cnvdat.h"
int gr_clip_fix_poly (int n, fix *vlist, fix *clist)
{
fix *tlist = (fix *)gr_alloc_temp (128*sizeof (fix));
fix x0, y0;
fix x1, y1;
int i, j;
/* clip left edge from vlist->tlist */
x0 = vlist[2*(n-1)];
y0 = vlist[2*(n-1)+1];
for (i=j=0; i<n; i++) {
x1 = vlist[2*i];
y1 = vlist[2*i+1];
if (x0 >= grd_fix_clip.left) {
/* start point is inside half plane */
if (x1 >= grd_fix_clip.left) {
/* both points inside half plane. output end point. */
tlist[2*j] = x1;
tlist[2*j+1] = y1;
j++;
} else {
/* edge exits half plane. output intersection. */
fix dx = x1-x0;
fix dy = y1-y0;
tlist[2*j] = grd_fix_clip.left;
tlist[2*j+1] = y0 + fix_mul_div (dy,(grd_fix_clip.left-x0),dx);
j++;
}
} else {
/* start point is outside half plane. */
if (x1 >= grd_fix_clip.left) {
/* edge enters half plane. output intersection and end point. */
fix dx = x1-x0;
fix dy = y1-y0;
if (x1 != grd_fix_clip.left) {
tlist[2*j] = grd_fix_clip.left;
tlist[2*j+1] = y0 + fix_mul_div (dy,(grd_fix_clip.left-x0),dx);
j++;
}
tlist[2*j] = x1;
tlist[2*j+1] = y1;
j++;
} else
/* both points outside, eliminate edge. */
;
}
x0=x1; y0=y1;
}
/* clip top edge from tlist->clist */
x0 = tlist[2*(j-1)];
y0 = tlist[2*(j-1)+1];
for (n=j, i=j=0; i<n; i++) {
x1 = tlist[2*i];
y1 = tlist[2*i+1];
if (y0 >= grd_fix_clip.top) {
/* start point is inside half plane */
if (y1 >= grd_fix_clip.top) {
/* both points inside half plane. output end point. */
clist[2*j] = x1;
clist[2*j+1] = y1;
j++;
} else {
/* edge exits half plane. output intersection. */
fix dx = x1-x0;
fix dy = y1-y0;
clist[2*j] = x0 + fix_mul_div (dx,(grd_fix_clip.top-y0),dy);
clist[2*j+1] = grd_fix_clip.top;
j++;
}
} else {
/* start point is outside half plane. */
if (y1 >= grd_fix_clip.top) {
/* edge enters half plane. output intersection and end point. */
fix dx = x1-x0;
fix dy = y1-y0;
if (y1 != grd_fix_clip.top) {
clist[2*j] = x0 + fix_mul_div (dx,(grd_fix_clip.top-y0),dy);
clist[2*j+1] = grd_fix_clip.top;
j++;
}
clist[2*j] = x1;
clist[2*j+1] = y1;
j++;
} else
/* both points outside, eliminate edge. */
;
}
x0=x1; y0=y1;
}
/* clip right edge from clist->tlist */
x0 = clist[2*(j-1)];
y0 = clist[2*(j-1)+1];
for (n=j, i=j=0; i<n; i++) {
x1 = clist[2*i];
y1 = clist[2*i+1];
if (x0 <= grd_fix_clip.right) {
/* start point is inside half plane */
if (x1 <= grd_fix_clip.right) {
/* both points inside half plane. output end point. */
tlist[2*j] = x1;
tlist[2*j+1] = y1;
j++;
} else {
/* edge exits half plane. output intersection. */
fix dx = x1-x0;
fix dy = y1-y0;
tlist[2*j] = grd_fix_clip.right;
tlist[2*j+1] = y0 + fix_mul_div (dy,(grd_fix_clip.right-x0),dx);
j++;
}
} else {
/* start point is outside half plane. */
if (x1 <= grd_fix_clip.right) {
/* edge enters half plane. output intersection and end point. */
fix dx = x1-x0;
fix dy = y1-y0;
if (x1 != grd_fix_clip.right) {
tlist[2*j] = grd_fix_clip.right;
tlist[2*j+1] = y0 + fix_mul_div (dy,(grd_fix_clip.right-x0),dx);
j++;
}
tlist[2*j] = x1;
tlist[2*j+1] = y1;
j++;
} else
/* both points outside, eliminate edge. */
;
}
x0=x1; y0=y1;
}
/* clip bottom edge from tlist->clist */
x0 = tlist[2*(j-1)];
y0 = tlist[2*(j-1)+1];
for (n=j, i=j=0; i<n; i++) {
x1 = tlist[2*i];
y1 = tlist[2*i+1];
if (y0 <= grd_fix_clip.bot) {
/* start point is inside half plane */
if (y1 <= grd_fix_clip.bot) {
/* both points inside half plane. output end point. */
clist[2*j] = x1;
clist[2*j+1] = y1;
j++;
} else {
/* edge exits half plane. output intersection. */
fix dx = x1-x0;
fix dy = y1-y0;
clist[2*j] = x0 + fix_mul_div (dx,(grd_fix_clip.bot-y0),dy);
clist[2*j+1] = grd_fix_clip.bot;
j++;
}
} else {
/* start point is outside half plane. */
if (y1 <= grd_fix_clip.bot) {
/* edge enters half plane. output intersection and end point. */
fix dx = x1-x0;
fix dy = y1-y0;
if (y1 != grd_fix_clip.bot) {
clist[2*j] = x0 + fix_mul_div (dx,(grd_fix_clip.bot-y0),dy);
clist[2*j+1] = grd_fix_clip.bot;
j++;
}
clist[2*j] = x1;
clist[2*j+1] = y1;
j++;
} else
/* both points outside, eliminate edge. */
;
}
x0=x1; y0=y1;
}
/* punt temporary vertex list. */
gr_free_temp (tlist);
/* return new number of vertices. */
return j;
}
@@ -0,0 +1,80 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clprect.c $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:14 $
*
* Routines for clipping rectangles to a rectangle.
*
* This file is part of the 2d library.
*
* $Log: clprect.c $
* Revision 1.4 1993/10/19 09:50:14 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/01 15:40:23 kaboom
* Converted to include clpcon.h instead of clip.h.
*
* Revision 1.2 1993/05/04 17:33:59 kaboom
* Changed to deal with new padded clipping regions.
*
* Revision 1.1 1993/02/22 14:41:56 kaboom
* Initial revision
*/
#include "clpcon.h"
#include "cnvdat.h"
/* clips the top, left, right, and bottom edges of a rectangle to the current
clip rectangle. pointers to the values are passed in so the values can be
modified. returns the clip code. */
int gr_clip_rect (short *left, short *top, short *right, short *bot)
{
int code = CLIP_NONE;
if (*right<=grd_clip.left || *left>=grd_clip.right ||
*bot<=grd_clip.top || *top>=grd_clip.bot)
/* rect is completely clipped. */
return CLIP_ALL;
if (*left < grd_clip.left) {
/* rect is off the left edge of the window. */
*left = grd_clip.left;
code |= CLIP_LEFT;
}
if (*right > grd_clip.right) {
/* off the right edge of the window. */
*right = grd_clip.right;
code |= CLIP_RIGHT;
}
if (*top < grd_clip.top) {
/* off the top of the window. */
*top = grd_clip.top;
code |= CLIP_TOP;
}
if (*bot > grd_clip.bot) {
/* off the bottom of the window. */
*bot = grd_clip.bot;
code |= CLIP_BOT;
}
return code;
}
@@ -0,0 +1,89 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/clpslin.c $
* $Revision: 1.2 $
* $Author: lmfeeney $
* $Date: 1994/06/11 01:13:24 $
*/
/* clip and fill shaded line -- using line fill table and grs_vertex interfaces.
These will be the preferred interfaces and are called from the original
gr_xxx canvas table x,y routines.
*/
#include "clpcon.h"
#include "clpfcn.h"
#include "clpltab.h"
#include "lg.h"
/* The amount of copying into and out of vertex's is quite
disgusting.
Also, becuase of the vertex interface, we've introduced a new
function call that we can't inline because it needs to return a
value.
*/
int gri_sline_clip (grs_vertex *v0, grs_vertex *v1)
{
int r;
fix x0, y0, x1, y1;
fix xb0, xb1, yb0, yb1;
fix i0, i1;
fix di;
fix pixels, pixels_0, pixels_1;
/* transfer back to x,y -- stolen from old gen_slin */
x0 = v0->x; y0 = v0->y; i0 = v0->i;
x1 = v1->x; y1 = v1->y; i1 = v1->i;
xb0 = x0; xb1 = x1; yb0 = y0; yb1 = y1;
pixels = lg_max(fix_abs(y1-y0),fix_abs(x1-x0));
if (pixels != 0) di = fix_div(i1-i0,pixels);
r = gr_clip_fix_line (&x0, &y0, &x1, &y1);
if (r != CLIP_ALL) {
// If x,y changed and we need to clip intensities,
if ((i0 != i1) &&
((x0 != xb0) || (y0 != yb0) || (x1 != xb1) || (y1 != yb1))) {
pixels_0 = lg_max(fix_abs(yb0-y0),fix_abs(xb0-x0)); // # pixels lost
pixels_1 = lg_max(fix_abs(yb1-y1),fix_abs(xb1-x1)); // for endpoints
i0 += fix_mul(di, pixels_0);
i1 -= fix_mul(di, pixels_1);
}
}
/* and transfer back to v0, v1 */
(v0->x) = x0; (v0->y) = y0; (v0->i) = i0;
(v1->x) = x1; (v1->y) = y1; (v1->i) = i1;
return r;
}
@@ -0,0 +1,282 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8opl.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/16 12:57:20 $
*
* full perspective texture mapper.
* scanline processors.
*
*/
#include "cnvdat.h"
#include "pertyp.h"
#include "plytyp.h"
// prototypes
void gri_opaque_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_opaque_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_opaque_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_opaque_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_opaque_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
// make SURE these come out in registers
register int x, k, y_cint;
register uchar *p;
register int gr_row, l_u_mask, l_v_mask, l_v_shift;
register fix l_du, l_dv, l_y_fix, l_scan_slope, test, l_u, l_v;
register uchar *bm_bits;
register fix l_dl, l_dt;
int l_x;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_u = pi->u;
l_v = pi->v;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_du = pi->du;
l_dv = pi->dv;
l_y_fix = pi->y_fix;
l_x = pi->x;
l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
l_u += l_x * l_du;
l_v += l_x * l_dv;
y_cint = fix_int(l_y_fix);
if (l_scan_slope < 0)
gr_row = -gr_row;
p = grd_bm.bits + l_x + (y_cint * grd_bm.row);
if (l_x < pi->xl) {
l_dl = pi->dyl;
l_dt = pi->dtl;
test = l_x * pi->dyl - y_cint * pi->dxl + pi->cl;
x = pi->xl - l_x;
l_x = pi->xl;
for (; x > 0; x--) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = bm_bits[k]; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
}
k = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (k != y_cint) {
p += gr_row;
test += l_dt;
} else
test += l_dl;
p++;
l_u += l_du;
l_v += l_dv;
}
}
if (l_x < pi->xr0) {
x = pi->xr0 - l_x;
l_x = pi->xr0;
for (; x > 0; x--) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*(p++) = bm_bits[k]; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
k = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (k != y_cint)
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
if (l_x < pi->xr) {
l_dl = pi->dyr;
test = l_x * l_dl - y_cint * pi->dxr + pi->cr;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
x = pi->xr - l_x;
l_dt = pi->dtr;
l_x = pi->xr;
for (; x > 0; x--) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = bm_bits[k]; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
}
k = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (k != y_cint) {
p += gr_row;
test += l_dt;
} else
test += l_dl;
p++;
l_u += l_du;
l_v += l_dv;
}
}
pi->y_fix = l_y_fix;
pi->x = l_x;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
void gri_opaque_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
int x_cint;
// locals used to speed PPC code
fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_x;
uchar *bm_bits;
uchar *p;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dxr = pi->dxr;
l_x_fix = pi->x_fix;
l_y = pi->y;
l_yr = pi->yr;
l_yr0 = pi->yr0;
l_yl = pi->yl;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
l_u += l_y * l_du;
l_v += l_y * l_dv;
x_cint = fix_int(l_x_fix);
p = grd_bm.bits + x_cint + l_y * gr_row;
if (l_y < l_yl) {
fix test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
for (; l_y < l_yl; l_y++) {
if (test <= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = bm_bits[k]; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtl;
p -= (temp_x - x_cint);
} else
test += l_dxl;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_y < l_yr0; l_y++) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = bm_bits[k]; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint)
p -= (temp_x - x_cint);
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
if (l_y < l_yr) {
fix test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
p = grd_bm.bits + x_cint + l_y * gr_row;
for (; l_y < l_yr; l_y++) {
if (test >= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = bm_bits[k]; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtr;
p -= (temp_x - x_cint);
} else
test += l_dxr;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
pi->x_fix = l_x_fix;
pi->y = l_y;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
extern void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
extern void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_opaque_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_hscan;
ps->scanline_func = (void (*)())gri_opaque_per_umap_hscan_scanline;
}
void gri_opaque_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_vscan;
ps->scanline_func = (void (*)())gri_opaque_per_umap_vscan_scanline;
}
+280
View File
@@ -0,0 +1,280 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/FL8F.c $
* $Revision: 1.4 $
* $Author: kevin $
* $Date: 1994/08/16 12:50:13 $
*
* Routines to floor texture map a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "fl8tmapdv.h"
#include "gente.h"
#include "poly.h"
#include "tmapint.h"
#include "vtab.h"
int gri_floor_umap_loop(grs_tmap_loop_info *tli);
int gri_floor_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, du, dv, dx, d;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
uchar t_wlog;
uint32_t t_mask;
int x, k;
uchar *t_bits;
uchar *p_dest;
fix inv;
uchar *t_clut;
uchar temp_pix;
int32_t *t_vtab;
#if InvDiv
inv = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(tli->left.u, inv);
du = fix_mul_asm_safe(tli->right.u, inv) - u;
v = fix_mul_asm_safe(tli->left.v, inv);
dv = fix_mul_asm_safe(tli->right.v, inv) - v;
#else
u = fix_div(tli->left.u, tli->w);
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div(tli->left.v, tli->w);
dv = fix_div(tli->right.v, tli->w) - v;
#endif
dx = tli->right.x - tli->left.x;
t_clut = tli->clut;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
t_vtab = tli->vtab;
t_bits = tli->bm.bits;
// handle PowerPC loop
do {
if ((d = fix_ceil(tli->right.x) - fix_ceil(tli->left.x)) > 0) {
d = fix_ceil(tli->left.x) - tli->left.x;
#if InvDiv
inv = fix_div(fix_make(1, 0), dx);
du = fix_mul_asm_safe(du, inv);
dv = fix_mul_asm_safe(dv, inv);
#else
du = fix_div(du, dx);
dv = fix_div(dv, dx);
#endif
u += fix_mul(du, d);
v += fix_mul(dv, d);
// copy out tli-> stuff into locals
p_dest = grd_bm.bits + (grd_bm.row * tli->y) + fix_cint(tli->left.x);
x = fix_cint(tli->right.x) - fix_cint(tli->left.x);
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (; x > 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
*(p_dest++) = t_bits[k]; // gr_fill_upixel(t_bits[k],x,t_y);
u += du;
v += dv;
}
break;
case GRL_TRANS:
for (; x > 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
temp_pix = t_bits[k];
if (temp_pix != 0)
*p_dest = temp_pix;
// gr_fill_upixel(t_bits[k],x,t_y);
p_dest++;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_LOG2:
for (; x > 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
*(p_dest++) = t_bits[k];
// gr_fill_upixel(t_bits[k],x,t_y);
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_LOG2:
for (; x > 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
temp_pix = t_bits[k];
if (temp_pix != 0)
*p_dest = temp_pix;
// gr_fill_upixel(t_bits[k],x,t_y);
p_dest++;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_CLUT:
for (; x > 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
*(p_dest++) = t_clut[t_bits[k]];
// gr_fill_upixel(tli->clut[t_bits[k]],x,t_y);
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_CLUT:
for (; x > 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0)
*p_dest = t_clut[k];
// gr_fill_upixel(tli->clut[k],x,t_y);
p_dest++;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_LOG2 | GRL_CLUT:
while (((intptr_t)p_dest & 3) != 0) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
*(p_dest++) = t_clut[t_bits[k]];
// gr_fill_upixel(tli->clut[t_bits[k]],x,t_y);
u += du;
v += dv;
x--;
}
while (x > 0) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
inv = t_clut[t_bits[k]];
// gr_fill_upixel(tli->clut[t_bits[k]],x,t_y);
u += du;
v += dv;
*p_dest = inv;
p_dest++;
x--;
}
for (; x > 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
*(p_dest++) = t_clut[t_bits[k]];
// gr_fill_upixel(tli->clut[t_bits[k]],x,t_y);
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_LOG2 | GRL_CLUT:
for (; x > 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0)
*p_dest = t_clut[k]; // gr_fill_upixel(tli->clut[k],x,t_y);
p_dest++;
u += du;
v += dv;
}
}
} else if (d < 0)
return TRUE; /* punt this tmap */
tli->w += tli->dw;
#if InvDiv
inv = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe((tli->left.u += tli->left.du), inv);
tli->right.u += tli->right.du;
du = fix_mul_asm_safe(tli->right.u, inv) - u;
v = fix_mul_asm_safe((tli->left.v += tli->left.dv), inv);
tli->right.v += tli->right.dv;
dv = fix_mul_asm_safe(tli->right.v, inv) - v;
#else
u = fix_div((tli->left.u += tli->left.du), tli->w);
tli->right.u += tli->right.du;
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div((tli->left.v += tli->left.dv), tli->w);
tli->right.v += tli->right.dv;
dv = fix_div(tli->right.v, tli->w) - v;
#endif
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
dx = tli->right.x - tli->left.x;
tli->y++;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
void gri_trans_floor_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_floor_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwx_edge;
tli->right_edge_func = (void (*)())gri_uvwx_edge;
}
void gri_opaque_floor_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE;
}
tli->loop_func = (void (*)())gri_floor_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwx_edge;
tli->right_edge_func = (void (*)())gri_uvwx_edge;
}
void gri_trans_clut_floor_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS | GRL_CLUT;
}
tli->loop_func = (void (*)())gri_floor_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwx_edge;
tli->right_edge_func = (void (*)())gri_uvwx_edge;
}
void gri_opaque_clut_floor_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
}
tli->loop_func = (void (*)())gri_floor_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwx_edge;
tli->right_edge_func = (void (*)())gri_uvwx_edge;
}
@@ -0,0 +1,60 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8bl.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/09/08 01:12:51 $
*
* Generic routines for texture mapping rsd bitmaps.
*
* This file is part of the 2d library.
*
*/
#include "bitmap.h"
#include "grs.h"
#include "ifcn.h"
#include "lg.h"
#include "rsdunpck.h"
#include "tmapint.h"
#include "tmaptab.h"
extern void flat8_flat8_smooth_hv_double_ubitmap(grs_bitmap *src, grs_bitmap *dst);
void gri_trans_blend_clut_lin_umap_init(grs_tmap_loop_info *ti);
void gri_trans_blend_clut_lin_umap_init(grs_tmap_loop_info *ti) {
if (grd_unpack_buf != NULL) {
grs_bitmap tbm;
tbm.row = 2 * ti->bm.w;
if (ti->bm.bits == grd_unpack_buf)
tbm.bits = ti->bm.bits + ti->bm.row * ti->bm.h;
else
tbm.bits = grd_unpack_buf;
flat8_flat8_smooth_hv_double_ubitmap(&(ti->bm), &tbm);
ti->n = BMT_FLAT8 * GRD_FUNCS + GRC_TRANS_CLUT_BILIN;
ti->bm.bits = tbm.bits;
ti->bm.row = tbm.row;
ti->bm.w *= 2;
ti->bm.h *= 2;
((void (*)(grs_tmap_loop_info *))(grd_tmap_init_table[ti->n]))(ti);
}
}
@@ -0,0 +1,265 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8bldbl.c $
* $Revision: 1.3 $
* $Author: kevin $
* $Date: 1994/12/01 14:59:38 $
*
* $Log: fl8bldbl.c $
* Revision 1.3 1994/12/01 14:59:38 kevin
* Added sub/bitmap blending routines.
*
* Revision 1.2 1994/09/08 00:01:07 kevin
* removed smooth_hv_doubler (replaced by asm version).
*
* Revision 1.1 1994/03/14 17:51:09 kevin
* Initial revision
*
*/
#include "blncon.h"
#include "blndat.h"
#include "blnfcn.h"
#include "cnvdat.h"
#include "grs.h"
#include "lg.h"
#include <string.h>
void flat8_flat8_v_double_ubitmap(grs_bitmap *bm) {
int i, j, bpv, row, b_row; /* loop controls, bottom pixel value */
uchar *src = bm->bits, *dst = grd_bm.bits, *src_nxt, *dst_nxt;
int dst_skip = grd_bm.row - bm->w, src_skip = bm->row - bm->w;
uchar *local_grd_half_blend;
local_grd_half_blend = grd_half_blend;
row = grd_bm.row;
b_row = bm->row;
LG_memcpy(dst, src, bm->w); /* first copy the top line */
for (i = 0; i < bm->h - 1; i++) /* for each row source, 2 destination */
{
src_nxt = src + b_row; /* next line of source */
dst += row; /* interpolated row */
dst_nxt = dst + row; /* next clone row */
for (j = 0; j < bm->w; j++) /* all pixels in vertical clone */
{
*dst++ = local_grd_half_blend[((bpv = *src_nxt++) << 8) | (*src++)];
*dst_nxt++ = bpv; /* is this faster than another memcpy? in asm probably? */
}
dst += dst_skip;
src += src_skip; /* get to the next line */
}
#ifdef FULL_FILL
memset(dst + row, 0, bm->w);
#endif
}
#define QSB_SIZE 4
#define LOG_QSB_SIZE 2
#define D_ROW 8 * QSB_SIZE
uchar *grd_last_sub_bm;
uchar grd_sub_bm_buffer[D_ROW * D_ROW];
void gri_flat8_hv_quadruple_sub_bitmap(grs_bitmap *src_bm, grs_bitmap *dst_bm, int u, int v);
void gri_flat8_hv_quadruple_sub_bitmap(grs_bitmap *src_bm, grs_bitmap *dst_bm, int u, int v) {
int i, j, full_h_blend;
uchar *src, *dst;
if (grd_log_blend_levels != 2) {
gr_free_blend();
gr_init_blend(2);
}
/* initialize destination bitmap parameters. */
dst_bm->bits = grd_sub_bm_buffer;
dst_bm->h = D_ROW;
dst_bm->row = dst_bm->w = D_ROW;
dst_bm->hlog = dst_bm->wlog = LOG_QSB_SIZE + 3;
/* get pointer to sub bitmap bits */
src = src_bm->bits + u + src_bm->row * v;
/* If we just did this bitmap, no need to do it again! */
if (src == grd_last_sub_bm)
return;
grd_last_sub_bm = src;
/* Fill in the middle of the destination bitmap */
dst = dst_bm->bits + (D_ROW + 1) * (D_ROW / 4);
if (v + QSB_SIZE < src_bm->h)
full_h_blend = 1;
else
full_h_blend = 0;
/* First horizontally blend the source bitmap into every fourth destination
* bitmap row. */
for (i = 0; i < QSB_SIZE + full_h_blend; i++) {
for (j = 0; j < QSB_SIZE; j++) {
if (u + j + 1 >= src_bm->w) {
/* if we're at the right edge of the source bitmap, just copy the right
* pixel.*/
dst[0] = dst[1] = dst[2] = dst[3] = src[j];
dst += 4;
} else {
int k = (src[j + 1]) | (src[j] << 8);
dst[0] = src[j];
dst[1] = grd_blend[k];
dst[2] = grd_blend[k + GR_BLEND_TABLE_SIZE];
dst[3] = grd_blend[k + 2 * GR_BLEND_TABLE_SIZE];
dst += 4;
}
}
dst += 4 * (D_ROW - QSB_SIZE);
src += src_bm->row;
}
/* Now verticaly blend the destination colums. */
dst = dst_bm->bits + (D_ROW + 1) * (D_ROW / 4);
for (i = 0; i < QSB_SIZE + full_h_blend - 1; i++) {
for (j = 0; j < 4 * QSB_SIZE; j++) {
int k = (dst[j + 4 * D_ROW]) | (dst[j] << 8);
dst[j + D_ROW] = grd_blend[k];
dst[j + 2 * D_ROW] = grd_blend[k + GR_BLEND_TABLE_SIZE];
dst[j + 3 * D_ROW] = grd_blend[k + 2 * GR_BLEND_TABLE_SIZE];
}
dst += 4 * D_ROW;
}
/* if we're at the bottom edge of the source bitmap, just copy the bottom row
* 3 times. */
if (full_h_blend == 0) {
LG_memcpy(dst + D_ROW, dst, 4 * QSB_SIZE);
LG_memcpy(dst + 2 * D_ROW, dst, 4 * QSB_SIZE);
LG_memcpy(dst + 3 * D_ROW, dst, 4 * QSB_SIZE);
}
/* copy the top row to fill out the top of the dest. */
dst = dst_bm->bits + (D_ROW + 1) * (D_ROW / 4);
for (i = 0; i < D_ROW / 4; i++) {
LG_memcpy(dst - D_ROW, dst, 4 * QSB_SIZE);
dst -= D_ROW;
}
/* copy the bottom row to fill out the bottom of the dest. */
dst = dst_bm->bits + (3 * D_ROW + 1) * (D_ROW / 4);
for (i = 0; i < D_ROW / 4; i++) {
LG_memcpy(dst, dst - D_ROW, 4 * QSB_SIZE);
dst += D_ROW;
}
/* copy the right and left colums to fill out the right and left edges. */
dst = dst_bm->bits;
for (i = 0; i < D_ROW; i++) {
memset(dst, dst[D_ROW / 4], D_ROW / 4);
memset(dst + 3 * D_ROW / 4, dst[(3 * D_ROW / 4) - 1], D_ROW / 4);
dst += D_ROW;
}
}
#define DSB_SIZE 8
#define LOG_DSB_SIZE 3
void gri_flat8_hv_double_sub_bitmap(grs_bitmap *src_bm, grs_bitmap *dst_bm, int u, int v);
void gri_flat8_hv_double_sub_bitmap(grs_bitmap *src_bm, grs_bitmap *dst_bm, int u, int v) {
int i, j, full_h_blend;
uchar *src, *dst;
if (grd_log_blend_levels != 2) {
gr_free_blend();
gr_init_blend(2);
}
/* initialize destination bitmap parameters. */
dst_bm->bits = grd_sub_bm_buffer;
dst_bm->h = D_ROW;
dst_bm->row = dst_bm->w = D_ROW;
dst_bm->hlog = dst_bm->wlog = LOG_DSB_SIZE + 2;
/* get pointer to sub bitmap bits */
src = src_bm->bits + u + src_bm->row * v;
/* If we just did this bitmap, no need to do it again! */
if (src == grd_last_sub_bm)
return;
grd_last_sub_bm = src;
/* Fill in the middle of the destination bitmap */
dst = dst_bm->bits + (D_ROW + 1) * (D_ROW / 4);
if (v + DSB_SIZE < src_bm->h)
full_h_blend = 1;
else
full_h_blend = 0;
/* First horizontally blend the source bitmap into every other destination
* bitmap row. */
for (i = 0; i < DSB_SIZE + full_h_blend; i++) {
for (j = 0; j < DSB_SIZE; j++) {
if (u + j + 1 >= src_bm->w) {
/* if we're at the right edge of the source bitmap, just copy the right
* pixel.*/
dst[0] = dst[1] = src[j];
dst += 2;
} else {
int k = (src[j + 1]) | (src[j] << 8);
dst[0] = src[j];
dst[1] = grd_half_blend[k];
dst += 2;
}
}
dst += 2 * (D_ROW - DSB_SIZE);
src += src_bm->row;
}
/* Now verticaly blend the destination colums. */
dst = dst_bm->bits + (D_ROW + 1) * (D_ROW / 4);
for (i = 0; i < DSB_SIZE + full_h_blend - 1; i++) {
for (j = 0; j < 2 * DSB_SIZE; j++) {
int k = (dst[j + 2 * D_ROW]) | (dst[j] << 8);
dst[j + D_ROW] = grd_half_blend[k];
}
dst += 2 * D_ROW;
}
/* if we're at the bottom edge of the source bitmap, just copy the bottom row
* 3 times. */
if (full_h_blend == 0)
LG_memcpy(dst + D_ROW, dst, 4 * QSB_SIZE);
// all this is unnecessary if we're just doing linear maps.
// /* copy the top row to fill out the top of the dest. */
// dst=dst_bm->bits+(D_ROW+1)*(D_ROW/4);
// for (i=0;i<D_ROW/4;i++) {
// memcpy(dst-D_ROW,dst,2*DSB_SIZE);
// dst-=D_ROW;
// }
// /* copy the bottom row to fill out the bottom of the dest. */
// dst=dst_bm->bits+(3*D_ROW+1)*(D_ROW/4);
// for (i=0;i<D_ROW/4;i++) {
// memcpy(dst,dst-D_ROW,2*DSB_SIZE);
// dst+=D_ROW;
// }
// /* copy the right and left colums to fill out the right and left edges.
// */ dst=dst_bm->bits; for (i=0;i<D_ROW;i++) {
// memset(dst,dst[D_ROW/4],D_ROW/4);
// memset(dst+3*D_ROW/4,dst[(3*D_ROW/4)-1],D_ROW/4);
// dst+=D_ROW;
// }
}
@@ -0,0 +1,62 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8chfl8.c $
* $Revision: 1.4 $
* $Author: kevin $
* $Date: 1993/10/26 02:23:49 $
* $Log: fl8chfl8.c $
* Revision 1.4 1993/10/26 02:23:49 kevin
* Use default clut if passed cl=NULL.
*
* Revision 1.3 1993/10/19 09:50:17 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/08 01:15:07 kaboom
* Changed quotes in #include lines to angle brackets for Watcom.
*
* Revision 1.1 1993/10/06 14:39:25 kevin
* Initial revision
*/
#include "cnvdat.h"
#include "scrmac.h"
/* draw an unclipped, horizontally flipped flat 8 bitmap to a flat 8
canvas through a color lookup table (clut). */
void flat8_clut_hflip_flat8_ubitmap(grs_bitmap *bm, short x, short y, uchar *cl) {
short w; /* bitmap width */
short h; /* height */
uchar *src; /* pointer into source bitmap */
uchar *dst; /* pointer into canvas memory */
ushort row;
if (cl == NULL)
cl = gr_get_clut();
h = bm->h;
src = bm->bits;
dst = grd_bm.bits + y * grd_bm.row + x + bm->w - 1;
while (h--) {
w = bm->w;
while (w--)
*dst-- = cl[*src++];
src += bm->row - bm->w;
dst += grd_bm.row + bm->w;
}
}
@@ -0,0 +1,110 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8clear.c $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:18 $
*
* Routines for clearing a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8clear.c $
* Revision 1.3 1993/10/19 09:50:18 kaboom
* Replaced #include "grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/08 01:15:08 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.1 1993/02/16 14:14:00 kaboom
* Initial revision
*/
#include "cnvdat.h"
#include "lg.h"
#include <string.h>
/* clear a flat8 canvas. */
void flat8_clear(long color) {
uchar *p;
int h;
int w;
int row;
ushort short_val;
double double_stack, doub_vl;
uint firstbytes, middoubles, lastbytes, fb, md, lb;
uchar *dst;
double *dst_doub;
uint temp;
color &= 0x00ff;
p = grd_bm.bits;
h = grd_bm.h;
w = grd_bm.w;
row = grd_bm.row;
if (w >= 16) // only do doubles if at least two of them (16 bytes)
{
// get a 64 bit version of color in doub_vl
short_val = (uchar)color | color << 8;
color = (int)short_val | ((int)short_val) << 16;
*(int *)(&double_stack) = color;
*((int *)(&double_stack) + 1) = color;
doub_vl = double_stack;
lastbytes = w;
firstbytes = (intptr_t)p & 3;
if (firstbytes != 0) // check for boundary problems
lastbytes -= firstbytes;
middoubles = lastbytes >> 3;
lastbytes -= middoubles << 3;
} else {
lastbytes = w;
middoubles = 0;
}
fb = firstbytes, md = middoubles, lb = lastbytes;
while (h--) {
// MLA - inlined this code
memset(p, color, w);
/*{
firstbytes = fb,middoubles = md,lastbytes = lb;
dst = p;
if (middoubles)
{
// first get to a 4 byte boundary
while (firstbytes--) *(dst++) = color;
dst_doub = (double *) dst;
// now do doubles
while (middoubles--) *(dst_doub++) = doub_vl;
dst = (uchar *) dst_doub;
}
// do remaining bytes
while (lastbytes--) *(dst++) = color;
}*/
p += row;
}
}
@@ -0,0 +1,105 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8clin.c $
* $Revision: 1.7 $
* $Author: kevin $
* $Date: 1994/10/17 14:59:57 $
*
* Routine to draw an rgb shaded line to a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8clin.c $
* Revision 1.7 1994/10/17 14:59:57 kevin
* Use palette macros in preparation for switch to palette globals.
*
* Revision 1.6 1994/06/11 01:24:08 lmfeeney
* guts of the routine moved to fl8{c,s}lin.h, per fill type
* line drawers are created by defining macros and including
* this file
*
* Revision 1.5 1994/05/06 18:18:38 lmfeeney
* rewritten for greater accuracy and speed
*
* Revision 1.4 1994/05/01 05:34:38 lmfeeney
* rewritten using simple dda algorithm (+ bit twiddle hack) for greater
* speed (20/30%) and improvement for e.g. diagonal lines
*
* Revision 1.3 1993/10/19 09:50:19 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/01 15:43:46 kaboom
* Pared down include files to reduce dependencies.
*
* Revision 1.1 1993/07/01 22:11:55 spaz
* Initial revision
*/
#include "cnvdat.h"
#include "fix.h"
#include "plytyp.h"
#include "scrdat.h"
#include <stdlib.h>
// MLA #pragma off (unreferenced)
#define fix_make_nof(x) fix_make(x, 0x0000)
#define macro_get_ipal(r, g, b) (long)((r >> 19) & 0x1f) | ((g >> 14) & 0x3e0) | ((b >> 9) & 0x7c00)
#undef macro_plot_rgb
#define macro_plot_rgb(x, p, i) \
do { \
p[x] = grd_ipal[i]; \
} while (0)
void gri_flat8_ucline_norm(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8clin.h"
}
#undef macro_plot_rgb
#define macro_plot_rgb(x, p, i) \
do { \
p[x] = (long)(((uchar *)parm)[(grd_ipal[i])]); \
} while (0)
void gri_flat8_ucline_clut(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8clin.h"
}
#undef macro_plot_rgb
#define macro_plot_rgb(x, p, i) \
do { \
p[x] = p[x] ^ (grd_ipal[i]); \
} while (0)
void gri_flat8_ucline_xor(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8clin.h"
}
/* punt */
#undef macro_plot_rgb
#define macro_plot_rgb(x, p, i) \
do { \
p[x] = (long)(((uchar *)parm)[(grd_ipal[i])]); \
} while (0)
void gri_flat8_ucline_blend(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8clin.h"
}
@@ -0,0 +1,322 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8clin.h $
* $Revision: 1.1 $
* $Author: lmfeeney $
* $Date: 1994/06/11 00:49:17 $
*/
/* This file is an UNCOMPILABLE code fragment */
/* Draw a gouraud-shaded line as specified by endpoint rgb value...
weird precision bugs abound due to precision errors
5/94 These have been (completely?) corrected. See test/clintest.c
See also note.txt for argument for correctness and precision safety
of current algorithm.
*/
/* NB: directionality policy -- reversible
Lines are drawn in order of increasing x or increasing y,
for lines that have greater x or y extent, repsectively.
This is done for all lines, including horiz., vert., and
45' lines (increasing x).
*/
/* NB: endpoint policy -- inclusive
The left and top endpoints are inclusive, i.e. 'trunc'-ed. The
right and bottom endpoints exclude the ceiling. This is
calculated by subtracting epsilon (i.e. 1/65536) from its
fixed-point representation, then trunc'ing.
This makes sense if you note that open interval on right
< ceil (x)
is the same as
<= trunc (x - e)
This means that it might not be necessary to go through the ugliness
of swapping endpoints, but I'm not convinced that there aren't
precision problems involved. Since wire-poly's overdraw, it's
really necessary to ensure that the same points are always drawn.
*/
fix x0, y0, x1, y1;
fix dx, dy; /* deltas in x and y */
fix t; /* tmp */
uchar r0, g0, b0, r1, g1, b1; /* rgb values of endpt colors */
fix r, g, b; /* current intensities */
fix dr, dg, db; /* deltas for each of rgb */
long i; /* color index */
uchar *p; /* ptr into canvas */
x0 = v0->x;
y0 = v0->y;
x1 = v1->x;
y1 = v1->y;
r0 = (uchar)(v0->u);
g0 = (uchar)(v0->v);
b0 = (uchar)(v0->w);
r1 = (uchar)(v1->u);
g1 = (uchar)(v1->v);
b1 = (uchar)(v1->w);
/* set endpoints
note that this cannot go negative or change octant, since the ==
case is excluded */
if (x0 < x1) {
x1 -= 1; /* e.g. - epsilon */
} else if (x0 > x1) {
x0 -= 1;
}
if (y0 < y1) {
y1 -= 1;
} else if (y0 > y1) {
y0 -= 1;
}
dx = fix_trunc(x1) - fix_trunc(x0); /* x extent in pixels, (macro is flakey) */
dx = fix_abs(dx);
dy = fix_trunc(y1) - fix_trunc(y0); /* y extent in pixels */
dy = fix_abs(dy);
if (dx == 0 && dy == 0)
return;
/* three cases: absolute value dx < = > dy
along the longer dimension, the fixpoint x0 (or y0) is treated
as an int
the points are swapped if needed and the rgb initial and deltas
are calculated accordingly
there are two or three sub-cases - a horizontal or vertical line,
and the dx or dy being added or subtracted. dx and dy
are kept as absolute values and +/- is managed in
two separate inner loops if it is a y change, since you need to
manage the canvas pointer
if y is being changed by 'dy' and x is being incremented, do a
FunkyBitCheck (TM) to see whether the integer part of y has changed
and if it has, resetting the the canvas pointer to the next row
if x is being changed by 'dx' and y is being incremented, just
add or subtract row to increment y in the canvas
the endpoints are walked inclusively in all cases, see above
45' degree lines are explicitly special cased -- because it
all runs as integers, but it's probably not frequent enough
to justify the check
*/
if (dx > dy) {
x0 = fix_int(x0);
x1 = fix_int(x1);
if (x0 < x1) {
r = fix_make(r0, 0);
g = fix_make(g0, 0);
b = fix_make(b0, 0);
dr = fix_div(fix_make_nof(r1 - r0), dx);
dg = fix_div(fix_make_nof(g1 - g0), dx);
db = fix_div(fix_make_nof(b1 - b0), dx);
p = grd_bm.bits + grd_bm.row * (fix_int(y0)); /* set canvas ptr */
} else {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
r = fix_make(r1, 0);
g = fix_make(g1, 0);
b = fix_make(b1, 0);
dr = fix_div(fix_make_nof(r0 - r1), dx);
dg = fix_div(fix_make_nof(g0 - g1), dx);
db = fix_div(fix_make_nof(b0 - b1), dx);
p = grd_bm.bits + grd_bm.row * (fix_int(y0));
}
if ((fix_int(y0)) == (fix_int(y1))) {
while (x0 <= x1) {
i = macro_get_ipal(r, g, b);
macro_plot_rgb(x0, p, i);
x0++;
r += dr;
g += dg;
b += db;
}
} else if (y0 < y1) {
dy = fix_div((y1 - y0), dx);
while (x0 <= x1) {
i = macro_get_ipal(r, g, b);
macro_plot_rgb(x0, p, i);
x0++;
y0 += dy;
p += (grd_bm.row & (-(fix_frac(y0) < dy)));
r += dr;
g += dg;
b += db;
}
} else {
dy = fix_div((y0 - y1), dx);
while (x0 <= x1) {
i = macro_get_ipal(r, g, b);
macro_plot_rgb(x0, p, i);
x0++;
p -= (grd_bm.row & (-(fix_frac(y0) < dy)));
y0 -= dy;
r += dr;
g += dg;
b += db;
}
}
}
else if (dy > dx) {
y0 = fix_int(y0);
y1 = fix_int(y1);
if (y0 < y1) {
r = fix_make(r0, 0);
g = fix_make(g0, 0);
b = fix_make(b0, 0);
dr = fix_div(fix_make_nof(r1 - r0), dy);
dg = fix_div(fix_make_nof(g1 - g0), dy);
db = fix_div(fix_make_nof(b1 - b0), dy);
p = grd_bm.bits + grd_bm.row * y0;
} else {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
r = fix_make(r1, 0);
g = fix_make(g1, 0);
b = fix_make(b1, 0);
dr = fix_div(fix_make_nof(r0 - r1), dy);
dg = fix_div(fix_make_nof(g0 - g1), dy);
db = fix_div(fix_make_nof(b0 - b1), dy);
p = grd_bm.bits + grd_bm.row * y0;
}
if ((fix_int(x0)) == (fix_int(x1))) {
x0 = fix_int(x0);
while (y0 <= y1) {
i = macro_get_ipal(r, g, b);
macro_plot_rgb(x0, p, i);
y0++;
p += grd_bm.row;
r += dr;
g += dg;
b += db;
}
} else {
dx = fix_div((x1 - x0), dy);
while (y0 <= y1) {
i = macro_get_ipal(r, g, b);
macro_plot_rgb(fix_fint(x0), p, i);
x0 += dx;
y0++;
p += grd_bm.row;
r += dr;
g += dg;
b += db;
}
}
} else { /* dy == dx, walk the x axis, all integers */
x0 = fix_int(x0);
x1 = fix_int(x1);
y0 = fix_int(y0);
y1 = fix_int(y1);
if (x0 < x1) {
r = fix_make(r0, 0);
g = fix_make(g0, 0);
b = fix_make(b0, 0);
dr = fix_div(fix_make_nof(r1 - r0), dx);
dg = fix_div(fix_make_nof(g1 - g0), dx);
db = fix_div(fix_make_nof(b1 - b0), dx);
p = grd_bm.bits + grd_bm.row * y0; /* set canvas ptr */
} else {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
r = fix_make(r1, 0);
g = fix_make(g1, 0);
b = fix_make(b1, 0);
dr = fix_div(fix_make_nof(r0 - r1), dx);
dg = fix_div(fix_make_nof(g0 - g1), dx);
db = fix_div(fix_make_nof(b0 - b1), dx);
p = grd_bm.bits + grd_bm.row * y0;
}
if (y0 < y1) {
while (y0 <= y1) {
i = macro_get_ipal(r, g, b);
macro_plot_rgb(x0, p, i);
x0++;
y0++;
p += grd_bm.row;
r += dr;
g += dg;
b += db;
}
} else {
while (y0 >= y1) {
i = macro_get_ipal(r, g, b);
macro_plot_rgb(x0, p, i);
x0++;
y0--;
p -= grd_bm.row;
r += dr;
g += dg;
b += db;
}
}
}
@@ -0,0 +1,397 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8cnv.c $
* $Revision: 1.78 $
* $Author: kevin $
* $Date: 1994/11/12 02:21:59 $
*
* General-purpose routines for drawing into straight-8 bitmaps.
* This file is part of the 2d library.
*
*/
#include "flat8.h"
#include "general.h"
#include "grnull.h"
#include "icanvas.h"
typedef void (*ptr_type)();
void (*flat8_canvas_table[GRD_CANVAS_FUNCS])() = {
(ptr_type)flat8_set_upixel, /* 8-bit pixel set/get */
(ptr_type)gen_set_pixel,
(ptr_type)flat8_get_upixel,
(ptr_type)flat8_get_pixel,
(ptr_type)flat8_set_upixel24, /* 24-bit pixel set/get */
(ptr_type)flat8_set_pixel24,
(ptr_type)flat8_get_upixel24,
(ptr_type)flat8_get_pixel24,
(ptr_type)flat8_clear, /* integral, straight primitives */
(ptr_type)temp_upoint,
(ptr_type)temp_point,
(ptr_type)flat8_set_upixel, /* 8-bit pixel set/get */
(ptr_type)gen_set_pixel_interrupt,
gr_null,
gr_null,
(ptr_type)gen_urect,
(ptr_type)gen_rect,
(ptr_type)gen_ubox,
(ptr_type)gen_box,
gr_null, /* fixed-point rendering primitives */
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
(ptr_type)temp_upoly,
(ptr_type)temp_poly,
(ptr_type)temp_uspoly,
(ptr_type)temp_spoly,
(ptr_type)temp_ucpoly,
(ptr_type)temp_cpoly,
(ptr_type)temp_utpoly,
(ptr_type)temp_tpoly,
(ptr_type)temp_ustpoly,
(ptr_type)temp_stpoly,
(ptr_type)gen_vox_rect,
(ptr_type)gen_vox_poly,
(ptr_type)gen_vox_cpoly,
(ptr_type)flat8_interp2_ubitmap,
(ptr_type)flat8_filter2_ubitmap,
gr_not_imp, // (ptr_type) gen_roll_ubitmap, MLA - not used?
gr_not_imp, // (ptr_type) gen_roll_bitmap, MLA - not used?
(ptr_type)temp_wall_umap,
gr_null,
(ptr_type)temp_lit_wall_umap,
gr_null,
(ptr_type)temp_clut_wall_umap,
gr_null,
(ptr_type)temp_floor_umap,
gr_null,
(ptr_type)temp_lit_floor_umap,
gr_null,
(ptr_type)temp_clut_floor_umap,
gr_null,
gr_null, /* linear texture mappers */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_lin_umap,
(ptr_type)temp_lin_map,
(ptr_type)temp_lin_umap,
(ptr_type)temp_lin_map,
(ptr_type)temp_lin_umap,
(ptr_type)temp_lin_map,
(ptr_type)temp_lin_umap,
(ptr_type)temp_lin_map,
gr_null, /* lit linear texture mappers */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_lit_lin_umap,
(ptr_type)temp_lit_lin_map,
gr_null,
gr_null,
(ptr_type)temp_lit_lin_umap,
(ptr_type)temp_lit_lin_map,
gr_null,
gr_null,
gr_null, /* clut linear texture mappers */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_clut_lin_umap,
(ptr_type)temp_clut_lin_map,
gr_null,
gr_null,
(ptr_type)temp_clut_lin_umap,
(ptr_type)temp_clut_lin_map,
(ptr_type)temp_clut_lin_umap,
(ptr_type)temp_clut_lin_map,
gr_null, /* solid linear mapper */
gr_null,
gr_null, /* perspective texture mappers */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_per_umap,
(ptr_type)temp_per_map,
gr_null,
gr_null,
(ptr_type)temp_per_umap,
(ptr_type)temp_per_map,
gr_null,
gr_null,
gr_null, /* lit perspective texture mappers */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_lit_per_umap,
gr_null,
gr_null,
gr_null,
(ptr_type)temp_lit_per_umap,
gr_null,
gr_null,
gr_null,
gr_null, /* clut perspective texture mappers */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_clut_per_umap,
(ptr_type)temp_clut_per_map,
gr_null,
gr_null,
(ptr_type)temp_clut_per_umap,
(ptr_type)temp_clut_per_map,
gr_null,
gr_null,
gr_null, /* solid perspective mapper */
gr_null,
(ptr_type)gen_int_ucircle, /* curves, should change to fixed-point */
(ptr_type)gen_int_circle,
(ptr_type)gen_fix_ucircle,
(ptr_type)gen_fix_circle,
(ptr_type)gen_int_udisk,
(ptr_type)gen_int_disk,
(ptr_type)gen_fix_udisk,
(ptr_type)gen_fix_disk,
(ptr_type)gen_int_urod,
(ptr_type)gen_int_rod,
(ptr_type)gen_fix_urod,
(ptr_type)gen_fix_rod,
// MLA - added these two for the device functions
(ptr_type)flat8_flat8_ubitmap, /* bitmap drawing functions. */
(ptr_type)gen_flat8_bitmap,
(ptr_type)flat8_mono_ubitmap,
(ptr_type)gen_mono_bitmap,
(ptr_type)temp_flat8_ubitmap,
(ptr_type)gen_flat8_bitmap,
(ptr_type)gen_flat24_ubitmap,
(ptr_type)gen_flat24_bitmap,
(ptr_type)temp_rsd8_ubitmap,
(ptr_type)temp_rsd8_bitmap,
(ptr_type)temp_tluc8_ubitmap,
(ptr_type)gen_tluc8_bitmap,
gr_null, /* bitmap drawing functions through a clut. */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_flat8_clut_ubitmap,
(ptr_type)gen_flat8_clut_bitmap,
gr_null,
gr_null,
(ptr_type)unpack_rsd8_clut_ubitmap,
(ptr_type)unpack_rsd8_clut_bitmap,
gr_null,
gr_null,
gr_null, /* rsd8 solid bitmap functions. No longer used. */
gr_null,
gr_null, /* bitmap scale functions. */
gr_null,
(ptr_type)flat8_mono_scale_ubitmap,
(ptr_type)flat8_mono_scale_bitmap,
(ptr_type)temp_scale_umap,
(ptr_type)temp_scale_map,
gr_null,
gr_null,
(ptr_type)temp_scale_umap,
(ptr_type)temp_scale_map,
(ptr_type)temp_scale_umap,
(ptr_type)temp_scale_map,
gr_null, /* rsd8 solid scale functions. No longer used. */
gr_null,
gr_null, /* clut scale functions. */
gr_null,
gr_null,
gr_null,
(ptr_type)temp_clut_scale_umap,
(ptr_type)temp_clut_scale_map,
gr_null,
gr_null,
(ptr_type)temp_clut_scale_umap,
(ptr_type)temp_clut_scale_map,
(ptr_type)temp_clut_scale_umap,
(ptr_type)temp_clut_scale_map,
gr_null, /* bitmap mask draw functions. */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_flat8_ubitmap,
(ptr_type)temp_flat8_mask_bitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap get functions. */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_get_flat8_ubitmap,
(ptr_type)gen_get_flat8_bitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap horizontal flip functions */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_hflip_flat8_ubitmap,
(ptr_type)gen_hflip_flat8_bitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap clut horizontal flip functions */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_clut_hflip_flat8_ubitmap,
(ptr_type)gen_clut_hflip_flat8_bitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap horizontal doubling. */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_flat8_h_double_ubitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap vertical doubling. */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_flat8_v_double_ubitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap horizontal and vertical doubling. */
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap smooth horizontal doubling. */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_flat8_smooth_h_double_ubitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap smooth vertical doubling. */
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null, /* bitmap smooth horizontal and vertical doubling. */
gr_null,
gr_null,
gr_null,
(ptr_type)flat8_flat8_smooth_hv_double_ubitmap,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
gr_null,
(ptr_type)gen_font_ustring, /* text/font functions. */
(ptr_type)gen_font_string,
(ptr_type)gen_font_scale_ustring,
(ptr_type)gen_font_scale_string,
(ptr_type)gen_font_uchar,
(ptr_type)gen_font_char,
(ptr_type)flat8_calc_row, /* utility functions. */
(ptr_type)flat8_sub_bitmap,
gr_null, /* placeholders for primitiveless chains */
gr_null,
};
@@ -0,0 +1,298 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/gencop.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/16 12:56:46 $
*
* full perspective texture mapper.
* scanline processors.
*
*/
#include "cnvdat.h"
#include "fl8tmapdv.h"
#include "pertyp.h"
#include "plytyp.h"
// prototypes
void gri_opaque_clut_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_opaque_clut_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_opaque_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_opaque_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_opaque_clut_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, y_cint;
uchar *p;
// locals used to speed PPC code
fix l_u, l_v, l_du, l_dv, l_y_fix, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_x, l_xl, l_xr, l_xr0, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_y;
uchar *bm_bits;
uchar *t_clut;
t_clut = pi->clut;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_y_fix = pi->y_fix;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_xr0 = pi->xr0;
l_x = pi->x;
l_xl = pi->xl;
l_xr = pi->xr;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_x * l_du;
l_v += l_x * l_dv;
y_cint = fix_int(l_y_fix);
if (l_scan_slope < 0)
gr_row = -gr_row;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
if (l_x < l_xl) {
fix test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
for (; l_x < l_xl; l_x++) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtl;
} else
test += l_dyl;
p++;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_x < l_xr0; l_x++) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*(p++) = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint)
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
if (l_x < l_xr) {
fix test = l_x * l_dyr - y_cint * pi->dxr + pi->cr;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
for (; l_x < l_xr; l_x++) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtr;
} else
test += l_dyr;
p++;
l_u += l_du;
l_v += l_dv;
}
}
pi->y_fix = l_y_fix;
pi->x = l_x;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
void gri_opaque_clut_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, x_cint;
// locals used to speed PPC code
fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_x;
uchar *bm_bits;
uchar *p;
uchar *t_clut;
t_clut = pi->clut;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dxr = pi->dxr;
l_x_fix = pi->x_fix;
l_y = pi->y;
l_yr = pi->yr;
l_yr0 = pi->yr0;
l_yl = pi->yl;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_y * l_du;
l_v += l_y * l_dv;
x_cint = fix_int(l_x_fix);
p = grd_bm.bits + x_cint + l_y * gr_row;
if (l_y < l_yl) {
fix test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
for (; l_y < l_yl; l_y++) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtl;
p -= (temp_x - x_cint);
} else
test += l_dxl;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_y < l_yr0; l_y++) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint)
p -= (temp_x - x_cint);
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
if (l_y < l_yr) {
fix test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
p = grd_bm.bits + x_cint + l_y * gr_row;
for (; l_y < l_yr; l_y++) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
*p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtr;
p -= (temp_x - x_cint);
} else
test += l_dxr;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
pi->x_fix = l_x_fix;
pi->y = l_y;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
extern void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
extern void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_opaque_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_hscan;
ps->scanline_func = (void (*)())gri_opaque_clut_per_umap_hscan_scanline;
}
void gri_opaque_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_vscan;
ps->scanline_func = (void (*)())gri_opaque_clut_per_umap_vscan_scanline;
}
@@ -0,0 +1,112 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8cply.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/10/17 14:59:58 $
*
* Routines for drawing flat shaded polygons onto a flat 8 canvas.
*
* This file is part of the 2d library.
*/
#include "cnvdat.h"
#include "fix.h"
#include "gente.h"
#include "poly.h"
#include "rgb.h"
#include "scrdat.h"
#include "tmapint.h"
// prototypes
int gri_cpoly_loop(grs_tmap_loop_info *ti);
void gri_cpoly_init(grs_tmap_loop_info *ti);
void gri_clut_cpoly_init(grs_tmap_loop_info *ti);
int gri_cpoly_loop(grs_tmap_loop_info *ti) {
int x, d;
fix dx, frac;
fix r, g, b, dr, dg, db;
do {
dx = ti->right.x - ti->left.x;
frac = fix_ceil(ti->left.x) - ti->left.x;
r = ti->left.u;
dr = fix_div(ti->right.u - r, dx);
r += fix_mul(frac, dr);
g = ti->left.v;
dg = fix_div(ti->right.v - g, dx);
g += fix_mul(frac, dg);
b = ti->left.i;
db = fix_div(ti->right.i - b, dx);
b += fix_mul(frac, db);
if ((d = fix_cint(ti->right.x) - fix_cint(ti->left.x)) > 0) {
switch (ti->bm.hlog) {
case GRL_OPAQUE:
for (x = fix_cint(ti->left.x); x < fix_cint(ti->right.x); x++) {
int j = gr_index_rgb(r, g, b);
ti->d[x] = grd_ipal[j];
r += dr, g += dg, b += db;
}
break;
case GRL_CLUT:
for (x = fix_cint(ti->left.x); x < fix_cint(ti->right.x); x++) {
int j = gr_index_rgb(r, g, b);
ti->d[x] = ti->clut[grd_ipal[j]];
r += dr, g += dg, b += db;
}
break;
}
} else if (d < 0) {
return TRUE;
}
/* update span extrema and destination. */
ti->left.x += ti->left.dx;
ti->right.x += ti->right.dx;
ti->left.u += ti->left.du;
ti->right.u += ti->right.du;
ti->left.v += ti->left.dv;
ti->right.v += ti->right.dv;
ti->left.i += ti->left.di;
ti->right.i += ti->right.di;
ti->d += grd_bm.row;
} while ((--(ti->n)) > 0);
return FALSE;
}
void gri_cpoly_init(grs_tmap_loop_info *ti) {
ti->bm.hlog = GRL_OPAQUE;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_cpoly_loop;
ti->top_edge_func = (void (*)())gri_rgbx_edge;
ti->bot_edge_func = (void (*)())gri_rgbx_edge;
}
void gri_clut_cpoly_init(grs_tmap_loop_info *ti) {
ti->bm.hlog = GRL_CLUT;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_cpoly_loop;
ti->top_edge_func = (void (*)())gri_rgbx_edge;
ti->bot_edge_func = (void (*)())gri_rgbx_edge;
}
@@ -0,0 +1,312 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/FL8CTP.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/16 12:57:23 $
*
* full perspective texture mapper.
* scanline processors.
*
*/
#include "cnvdat.h"
#include "fl8tmapdv.h"
#include "pertyp.h"
#include "plytyp.h"
// prototypes
void gri_trans_clut_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_trans_clut_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_trans_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_trans_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_trans_clut_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, y_cint;
uchar *p;
// ltc_als used to speed PPC code
fix l_u, l_v, l_du, l_dv, l_y_fix, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_x, l_xl, l_xr, l_xr0, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_y;
uchar *bm_bits;
uchar *t_clut, temp_pix;
t_clut = pi->clut;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_y_fix = pi->y_fix;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_xr0 = pi->xr0;
l_x = pi->x;
l_xl = pi->xl;
l_xr = pi->xr;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_x * l_du;
l_v += l_x * l_dv;
y_cint = fix_int(l_y_fix);
if (l_scan_slope < 0)
gr_row = -gr_row;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
if (l_x < l_xl) {
fix test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
for (; l_x < l_xl; l_x++) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = t_clut[temp_pix]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtl;
} else
test += l_dyl;
p++;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_x < l_xr0; l_x++) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = t_clut[temp_pix]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint)
p += gr_row;
p++;
l_u += l_du;
l_v += l_dv;
}
if (l_x < l_xr) {
fix test = l_x * l_dyr - y_cint * pi->dxr + pi->cr;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
for (; l_x < l_xr; l_x++) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = t_clut[temp_pix]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtr;
} else
test += l_dyr;
p++;
l_u += l_du;
l_v += l_dv;
}
}
pi->y_fix = l_y_fix;
pi->x = l_x;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
void gri_trans_clut_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, x_cint;
// locals used to speed PPC code
fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_x;
uchar *bm_bits;
uchar *p;
uchar *t_clut, temp_pix;
t_clut = pi->clut;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dxr = pi->dxr;
l_x_fix = pi->x_fix;
l_y = pi->y;
l_yr = pi->yr;
l_yr0 = pi->yr0;
l_yl = pi->yl;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_y * l_du;
l_v += l_y * l_dv;
x_cint = fix_int(l_x_fix);
p = grd_bm.bits + x_cint + l_y * gr_row;
if (l_y < l_yl) {
fix test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
for (; l_y < l_yl; l_y++) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = t_clut[temp_pix]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtl;
p -= (temp_x - x_cint);
} else
test += l_dxl;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_y < l_yr0; l_y++) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = t_clut[temp_pix]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint)
p -= (temp_x - x_cint);
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
if (l_y < l_yr) {
fix test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
p = grd_bm.bits + x_cint + l_y * gr_row;
for (; l_y < l_yr; l_y++) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = t_clut[temp_pix]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtr;
p -= (temp_x - x_cint);
} else
test += l_dxr;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
pi->x_fix = l_x_fix;
pi->y = l_y;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
extern void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
extern void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_trans_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_hscan;
ps->scanline_func = (void (*)())gri_trans_clut_per_umap_hscan_scanline;
}
void gri_trans_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_vscan;
ps->scanline_func = (void (*)())gri_trans_clut_per_umap_vscan_scanline;
}
@@ -0,0 +1,176 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
//
// $Source: r:/prj/lib/src/2d/RCS/fl8dbl.asm $
// $Revision: 1.3 $
// $Author: kevin $
// $Date: 1994/09/08 00:00:18 $
//
// Bitmap doubling primitives.
//
#include <stdbool.h>
#include "blndat.h"
#include "grs.h"
#include "lg.h"
// ------------------------------------------------------------------------
// PowerPC routines
// ------------------------------------------------------------------------
// ========================================================================
void flat8_flat8_h_double_ubitmap(grs_bitmap *bm) {
DEBUG("%s: call mark", __FUNCTION__);
/* int h,v,endh,endv;
uchar *src=bm->bits, *dst=grd_bm.bits;
long srcAdd,dstAdd;
uchar temp;
srcAdd = bm->row-bm->w;
dstAdd = grd_bm.row - (bm->w<<1);
endh = bm->w;
endv = bm->h;
for (v=0; v<endv; v++)
{
for (h=0; h<endh; h++)
{
temp = *(src++);
*(dst++) = temp;
*(dst++) = temp;
}
src+=srcAdd;
dst+=dstAdd;
}*/
}
// ========================================================================
void flat8_flat8_smooth_h_double_ubitmap(grs_bitmap *srcb, grs_bitmap *dstb) {
int h, v, endh, endv;
uchar *src = srcb->bits, *dst = dstb->bits;
long srcAdd, dstAdd;
ushort curpix, tempshort;
uchar *local_grd_half_blend;
local_grd_half_blend = grd_half_blend;
if (!local_grd_half_blend)
return;
srcAdd = (srcb->row - srcb->w) - 1;
dstAdd = dstb->row - (srcb->w << 1);
endh = srcb->w - 1;
endv = srcb->h;
for (v = 0; v < endv; v++) {
curpix = *(short *)src;
src += 2;
for (h = 0; h < endh; h++) {
tempshort = curpix & 0xff00;
tempshort |= local_grd_half_blend[curpix];
*(ushort *)dst = tempshort;
dst += 2;
curpix = (curpix << 8) | *(src++);
}
// double last pixel
curpix >>= 8;
*(dst++) = curpix;
*(dst++) = curpix;
src += srcAdd;
dst += dstAdd;
}
}
// ========================================================================
// src = eax, dest = edx
void flat8_flat8_smooth_hv_double_ubitmap(grs_bitmap *src, grs_bitmap *dst) {
int tempH, tempW, temp, savetemp;
uchar *srcPtr, *dstPtr;
uchar *shvd_read_row1, *shvd_write, *shvd_read_row2, *shvd_read_blend;
ushort tempc;
dstPtr = dst->bits;
srcPtr = src->bits;
// HAX HAX HAX no smooth doubling for now!
for (int y = 0; y < src->h; y++) {
for (int x = 0; x < src->w; x++) {
*(dstPtr) = *srcPtr;
*(dstPtr + 1) = *srcPtr;
*(dstPtr + src->w * 2) = *srcPtr;
*((dstPtr + src->w * 2) + 1) = *srcPtr;
dstPtr += 2;
srcPtr++;
}
dstPtr += src->w * 2;
}
return;
/* // WH - unused code
dst->row <<= 1;
flat8_flat8_smooth_h_double_ubitmap(src, dst);
dst->row = tempW = dst->row >> 1;
dstPtr = dst->bits;
tempH = src->h - 1;
temp = src->w << 1;
dstPtr += temp;
temp = -temp;
shvd_read_row1 = dstPtr;
dstPtr += tempW;
shvd_write = dstPtr - 1;
dstPtr += tempW;
shvd_read_row2 = dstPtr;
shvd_read_blend = grd_half_blend;
savetemp = temp;
do {
do {
tempc = shvd_read_row1[temp];
tempc |= ((ushort)shvd_read_row2[temp]) << 8;
temp++;
shvd_write[temp] = shvd_read_blend[tempc];
} while (temp != 0);
if (--tempH == 0)
break;
shvd_read_row1 = dstPtr;
dstPtr += tempW;
shvd_write = dstPtr - 1;
dstPtr += tempW;
shvd_read_row2 = dstPtr;
temp = savetemp;
} while (true);
// do last row
srcPtr = dstPtr + savetemp;
dstPtr += tempW + savetemp;
savetemp = -savetemp;
for (; savetemp > 0; savetemp--)
*(dstPtr++) = *(srcPtr++);
*/
}
@@ -0,0 +1,86 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8fl8.c $
* $Revision: 1.5 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:21 $
*
* Routines for drawing flat 8 bitmaps into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8fl8.c $
* Revision 1.5 1993/10/19 09:50:21 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.4 1993/10/08 01:15:13 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.3 1993/07/12 23:30:56 kaboom
* Inline memmove() uses movs.
*
* Revision 1.2 1993/03/29 18:22:11 kaboom
* Changed to inline version of memmove.
*
* Revision 1.1 1993/02/16 14:14:16 kaboom
* Initial revision
*
********************************************************************
* Log from old flat8.c:
* Revision 1.7 1992/12/14 18:08:40 kaboom
* Added handing for transparency in the flat8_flat8_ubitmap()
* routine.
*/
#include "bitmap.h"
#include "cnvdat.h"
#include "lg.h"
#include <string.h>
void flat8_flat8_ubitmap(grs_bitmap *bm, short x, short y) {
uchar *m_src;
uchar *m_dst;
int w = bm->w;
int h = bm->h;
int i;
int brow, grow;
brow = bm->row;
grow = grd_bm.row;
m_src = bm->bits;
m_dst = grd_bm.bits + grow * y + x;
if (bm->flags & BMF_TRANS)
while (h--) {
for (i = 0; i < w; i++)
if (m_src[i] != 0)
m_dst[i] = m_src[i];
m_src += brow;
m_dst += grow;
}
else
while (h--) {
memmove(m_dst, m_src, w);
m_src += brow;
m_dst += grow;
}
}
@@ -0,0 +1,71 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8fl8c.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/10/04 18:45:42 $
*
* Routines for drawing flat8 bitmaps into a flat8 canvas through a clut.
*
* This file is part of the 2d library.
*
* $Log: fl8fl8c.c $
* Revision 1.2 1994/10/04 18:45:42 kevin
* added clut fill mode specific function. Renamed old proc.
*
* Revision 1.1 1994/03/15 13:15:51 kevin
* Initial revision
*
*/
#include "bitmap.h"
#include "cnvdat.h"
#include "fl8tf.h"
void gri_flat8_fill_clut_ubitmap(grs_bitmap *bm, short x, short y) {
gri_flat8_clut_ubitmap(bm, x, y, (uchar *)(grd_gc.fill_parm));
}
void gri_flat8_clut_ubitmap(grs_bitmap *bm, short x, short y, uchar *cl) {
uchar *src, *dst, *srcf;
short w = bm->w;
short h = bm->h;
int ds = bm->row - w;
int dd = grd_bm.row - w;
src = bm->bits;
dst = grd_bm.bits + grd_bm.row * y + x;
if (bm->flags & BMF_TRANS)
while (h--) {
for (srcf = src + w; src < srcf; src++, dst++)
if ((*src) != 0)
*dst = cl[*src];
src += ds;
dst += dd;
}
else
while (h--) {
for (srcf = src + w; src < srcf; src++, dst++)
*dst = cl[*src];
src += ds;
dst += dd;
}
}
@@ -0,0 +1,152 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8fl8m.c $
* $Revision: 1.3 $
* $Author: kevin $
* $Date: 1994/10/04 18:46:16 $
*
* Routines for masking flat 8 bitmaps into a flat 8 canvas
* through a stencil.
*
* This file is part of the 2d library.
*
* $Log: fl8fl8m.c $
* Revision 1.3 1994/10/04 18:46:16 kevin
* added clut fill mode specific function. Renamed old proc.
*
* Revision 1.2 1994/08/16 18:29:35 kevin
* fixed several bugs.
*
* Revision 1.1 1994/08/16 13:14:22 kevin
* Initial revision
*
*/
#include "bitmap.h"
#include "clip.h"
#include "cnvdat.h"
#include "fl8tf.h"
#include "grs.h"
#include "lg.h"
#include <string.h>
extern int gen_flat8_bitmap(grs_bitmap *bm, short x, short y);
int gri_flat8_mask_bitmap(grs_bitmap *bm, short x, short y, grs_stencil *sten) {
if (sten == NULL)
return gen_flat8_bitmap(bm, x, y);
else {
int yf = y + bm->h;
uchar *dst;
uchar *src = bm->bits - x;
if (yf > grd_clip.bot)
yf = grd_clip.bot;
if (y < grd_clip.top) {
src += (grd_clip.top - y) * bm->row;
y = grd_clip.top;
}
dst = grd_bm.bits + y * grd_bm.row;
for (; y < yf; y++) {
int xi = x, xf = x + bm->w;
grs_sten_elem *s;
#ifdef NEW_STENCILS
s = &(sten[y]);
#else
s = &((sten->elem)[y]);
#endif
for (; s->r <= xi;) {
s = s->n;
if (s == NULL)
break;
}
if (s != NULL) {
if (s->l > xi)
xi = s->l;
if (s->r < xf)
xf = s->r;
if (xf > xi) {
if (bm->flags & BMF_TRANS) {
int i;
for (i = xi; i < xf; i++)
if (src[i])
dst[i] = src[i];
} else {
LG_memmove(dst + xi, src + xi, xf - xi);
}
}
}
src += bm->row;
dst += grd_bm.row;
}
}
return CLIP_NONE; /* actually, who knows? */
}
extern int gen_flat8_clut_bitmap(grs_bitmap *bm, short x, short y, uchar *clut);
int gri_flat8_mask_fill_clut_bitmap(grs_bitmap *bm, short x, short y, grs_stencil *sten) {
uchar *clut = (uchar *)(grd_gc.fill_parm);
if (sten == NULL)
return gen_flat8_clut_bitmap(bm, x, y, clut);
else {
int yf = y + bm->h;
uchar *dst;
uchar *src = bm->bits - x;
if (yf > grd_clip.bot)
yf = grd_clip.bot;
if (y < grd_clip.top) {
src += (grd_clip.top - y) * bm->row;
y = grd_clip.top;
}
dst = grd_bm.bits + y * grd_bm.row;
for (; y < yf; y++) {
int xi = x, xf = x + bm->w;
grs_sten_elem *s;
#ifdef NEW_STENCILS
s = &(sten[y]);
#else
s = &((sten->elem)[y]);
#endif
for (; s->r <= xi;) {
s = s->n;
if (s == NULL)
break;
}
if (s != NULL) {
if (s->l > xi)
xi = s->l;
if (s->r < xf)
xf = s->r;
if (xf > xi) {
int i;
if (bm->flags & BMF_TRANS) {
for (i = xi; i < xf; i++)
if (src[i])
dst[i] = clut[src[i]];
} else {
for (i = xi; i < xf; i++)
dst[i] = clut[src[i]];
}
}
}
src += bm->row;
dst += grd_bm.row;
}
}
return CLIP_NONE; /* actually, who knows? */
}
@@ -0,0 +1,90 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8fltr2.c $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 09:52:36 $
*
* Routine for scaling down by 2 with filtering onto a flat8 canvas
*
* This file is part of the 2d library.
*
* $Log: fl8fltr2.c $
* Revision 1.3 1993/10/19 09:52:36 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/08 01:15:14 kaboom
* Changed quotes in #include lines to angle brackets for Watcom.
*
* Revision 1.1 1993/08/05 20:06:53 jaemz
* Initial revision
*/
#include "bitmap.h"
#include "cnvdat.h"
#include "scrdat.h"
/* Assumes bm is flat, assumes canvas is big enough to
hold it, as it is, unclipped */
void flat8_filter2_ubitmap(grs_bitmap *bm) {
grs_rgb a;
int i, j;
uchar *src, *dst;
uchar *c;
int ds;
int dd;
dst = grd_bm.bits;
src = bm->bits;
ds = 2 * bm->row - bm->w;
dd = grd_bm.row - grd_bm.w;
/* variables
a,src,dst,bm->row,grd_ipal,grd_bpal */
/* Cycle through rows and do horizontal strips */
for (j = bm->h; j > 0; j -= 2) {
for (i = bm->w; i > 0; i -= 2) {
a = (grd_bpal[*src] >> 2) & 0x3fc7f8ff;
src++;
a += (grd_bpal[*src] >> 2) & 0x3fc7f8ff;
src += bm->row;
a += (grd_bpal[*src] >> 2) & 0x3fc7f8ff;
src--;
a += (grd_bpal[*src] >> 2) & 0x3fc7f8ff;
src -= bm->row;
src += 2;
c = grd_ipal;
a = a >> 5;
c += a & 0x1f;
a = a >> 6;
c += a & 0x3e0;
a = a >> 6;
c += a & 0x7c00;
*dst = *c;
dst++;
}
src += ds;
dst += dd;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,71 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8g24.c $
* $Revision: 1.4 $
* $Author: kevin $
* $Date: 1994/10/17 14:59:58 $
*
* Routines for reading 24-bit pixels from a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8g24.c $
* Revision 1.4 1994/10/17 14:59:58 kevin
* Use palette macros in preparation for switch to palette globals.
*
* Revision 1.3 1993/10/19 09:50:22 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/01 15:44:52 kaboom
* Converted to include clpcon.h instead of clip.h.
*
* Revision 1.1 1993/09/02 20:03:41 kaboom
* Initial revision
*/
#include "clpcon.h"
#include "cnvdat.h"
#include "scrdat.h"
/* set an unclipped pixel in bank-switched memory. */
long flat8_get_upixel24(short x, short y) {
uchar *p;
long *r;
int i;
p = grd_canvas->bm.bits + grd_canvas->bm.row * y + x;
i = *p;
r = (long *)(grd_pal + 3 * i);
return *r & 0x00ffffff;
}
/* set a clipped pixel in bank-switched memory. return the clip code. */
long flat8_get_pixel24(short x, short y) {
uchar *p;
long *r;
int i;
if (x < grd_clip.left || x >= grd_clip.right || y < grd_clip.top || y >= grd_clip.bot)
return CLIP_ALL;
p = grd_canvas->bm.bits + grd_canvas->bm.row * y + x;
i = *p;
r = (long *)(grd_pal + 3 * i);
return *r & 0x00ffffff;
}
@@ -0,0 +1,59 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8gfl8.c $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:23 $
*
* Routines for reading flat 8 bitmaps from a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8gfl8.c $
* Revision 1.3 1993/10/19 09:50:23 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/08 01:15:14 kaboom
* Changed quotes in #include lines to angle brackets for Watcom.
*
* Revision 1.1 1993/02/16 14:15:10 kaboom
* Initial revision
*/
#include "cnvdat.h"
#include "lg.h"
#include <string.h>
void flat8_get_flat8_ubitmap(grs_bitmap *bm, short x, short y) {
uchar *src;
uchar *dst;
short h = bm->h;
short w = bm->w;
ushort brow = bm->row;
ushort grow = grd_bm.row;
src = grd_bm.bits + grow * y + x;
dst = bm->bits;
while (h--) {
LG_memmove(dst, src, w);
src += grow;
dst += brow;
}
}
@@ -0,0 +1,60 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8gpix.c $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:32 $
*
* Routines for reading pixels from a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8gpix.c $
* Revision 1.3 1993/10/19 09:50:32 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/08 01:15:15 kaboom
* Changed quotes in #include lines to angle brackets for Watcom.
*
* Revision 1.1 1993/02/16 14:15:28 kaboom
* Initial revision
*/
#include "cnvdat.h"
/* returns value of the unclipped pixel at (x, y). */
long flat8_get_upixel(short x, short y) {
uchar *p;
p = grd_bm.bits + grd_bm.row * y + x;
return (long)*p;
}
/* returns value of the clipped pixel at (x, y). returns -1 if pixel isn't
in the window bounds. */
long flat8_get_pixel(short x, short y) {
uchar *p;
if (x < grd_clip.left || x >= grd_clip.right || y < grd_clip.top || y >= grd_clip.bot)
return -1;
p = grd_bm.bits + grd_bm.row * y + x;
return (long)*p;
}
@@ -0,0 +1,63 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8hfl8.c $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:33 $
*
* flat 8 bitmap horizontal flip routine.
*
* This file is part of the 2d library.
*
* $Log: fl8hfl8.c $
* Revision 1.3 1993/10/19 09:50:33 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/08 01:15:16 kaboom
* Changed quotes in #include lines to angle brackets for Watcom.
*
* Revision 1.1 1993/06/06 15:09:08 kaboom
* Initial revision
*/
#include "cnvdat.h"
/* draw an unclipped, horizontally flipped flat 8 bitmap to a flat 8
canvas. */
void flat8_hflip_flat8_ubitmap(grs_bitmap *bm, short x, short y) {
short w; /* bitmap width */
short h; /* height */
uchar *src; /* pointer into source bitmap */
uchar *dst; /* pointer into canvas memory */
ushort brow = bm->row;
ushort grow = grd_bm.row;
short bw = bm->w;
h = bm->h;
src = bm->bits;
dst = grd_bm.bits + y * grow + x + bw - 1;
while (h--) {
w = bw;
while (w--)
*dst-- = *src++;
src += brow - bw;
dst += grow + bw;
}
}
@@ -0,0 +1,124 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8hlin.c $
* $Revision: 1.8 $
* $Author: lmfeeney $
* $Date: 1994/08/12 01:09:33 $
*
* Routines for horizontal drawing lines into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8hlin.c $
* Revision 1.8 1994/08/12 01:09:33 lmfeeney
* get fill/solid from right place
*
* Revision 1.7 1994/06/14 00:04:22 lmfeeney
* fixed stupid error in xor lines
*
* Revision 1.6 1994/06/11 01:46:09 lmfeeney
* unclipped flat8 line drawers routines for each fill type
* canvas values as parameters
*
* Revision 1.5 1993/10/19 09:50:34 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.4 1993/10/08 01:15:17 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.3 1993/05/04 18:43:15 kaboom
* Changed hline to be inclusive of its endpoints.
*
* Revision 1.2 1993/03/02 19:38:32 kaboom
* Changed not to draw rightmost pixel.
*
* Revision 1.1 1993/02/22 14:44:24 kaboom
* Initial revision
*/
#include "cnvdat.h"
#include "ctxmac.h"
#include "fill.h"
#include "lg.h"
#include <string.h>
/* draw an unclipped horizontal line with integral coordinates. */
// MLA #pragma off (unreferenced)
/* clut should be in _ns everywhere, it doesn't need its own function */
void gri_flat8_uhline_ns(short x0, short y0, short x1, long c, long parm) {
uchar *p;
short t;
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
}
if (gr_get_fill_type() == FILL_SOLID)
c = (uchar)parm;
p = grd_bm.bits + y0 * grd_bm.row + x0;
memset(p, c, x1 - x0 + 1);
}
void gri_flat8_uhline_clut(short x0, short y0, short x1, long c, long parm) {
uchar *p;
short t;
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
}
c = (long)(((uchar *)parm)[c]);
p = grd_bm.bits + y0 * grd_bm.row + x0;
memset(p, c, x1 - x0 + 1);
}
void gri_flat8_uhline_xor(short x0, short y0, short x1, long c, long parm) {
uchar *p;
short t;
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
}
for (p = grd_bm.bits + y0 * grd_bm.row + x0; x0 <= x1; p++, x0++)
*p = *p ^ c;
}
/* punt */
void gri_flat8_uhline_blend(short x0, short y0, short x1, long c, long parm) {
uchar *p;
short t;
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
}
p = grd_bm.bits + y0 * grd_bm.row + x0;
memset(p, c, x1 - x0 + 1);
}
@@ -0,0 +1,200 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/genlf.c $
* $Revision: 1.3 $
* $Author: kevin $
* $Date: 1994/08/16 12:50:14 $
*
* Routines to floor texture map a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "fl8tmapdv.h"
#include "gente.h"
#include "poly.h"
#include "scrmac.h"
#include "tmapint.h"
#include "vtab.h"
int gri_lit_floor_umap_loop(grs_tmap_loop_info *tli);
int gri_lit_floor_umap_loop(grs_tmap_loop_info *tli) {
#if InvDiv
fix inv = fix_div(fix_make(1, 0), tli->w);
fix u = fix_mul_asm_safe(tli->left.u, inv);
fix du = fix_mul_asm_safe(tli->right.u, inv) - u;
fix v = fix_mul_asm_safe(tli->left.v, inv);
fix dv = fix_mul_asm_safe(tli->right.v, inv) - v;
fix i = fix_mul_asm_safe(tli->left.i, inv);
fix di = fix_mul_asm_safe(tli->right.i, inv) - i;
#else
fix u = fix_div(tli->left.u, tli->w);
fix du = fix_div(tli->right.u, tli->w) - u;
fix v = fix_div(tli->left.v, tli->w);
fix dv = fix_div(tli->right.v, tli->w) - v;
fix i = fix_div(tli->left.i, tli->w);
fix di = fix_div(tli->right.i, tli->w) - i;
#endif
ulong t_mask = tli->mask;
uchar t_wlog = tli->bm.wlog;
uchar *g_ltab = grd_screen->ltab;
int32_t *t_vtab = tli->vtab;
uchar *t_bits = tli->bm.bits;
do {
fix dx = tli->right.x - tli->left.x;
if (dx > 0)
{
#if InvDiv
inv = fix_div(fix_make(1, 0) << 8, dx);
di = fix_mul_asm_safe_light(di, inv);
inv >>= 8;
du = fix_mul_asm_safe(du, inv);
dv = fix_mul_asm_safe(dv, inv);
#else
du = fix_div(du, dx);
dv = fix_div(dv, dx);
di = fix_div(di, dx);
#endif
fix d = fix_ceil(tli->left.x) - tli->left.x;
u += fix_mul(du, d);
v += fix_mul(dv, d);
i += fix_mul(di, d);
uchar *p_dest = grd_bm.bits + (grd_bm.row * tli->y) + fix_cint(tli->left.x);
int x = fix_cint(tli->right.x) - fix_cint(tli->left.x);
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (; x > 0; x--) {
int k = t_vtab[fix_fint(v)] + fix_fint(u);
*(p_dest++) = g_ltab[t_bits[k] + fix_light(i)];
// gr_fill_upixel(g_ltab[t_bits[k]+fix_light(i)],x,t_y);
}
break;
case GRL_TRANS:
for (; x > 0; x--) {
int k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0) *p_dest = g_ltab[k + fix_light(i)];
// gr_fill_upixel(g_ltab[k+fix_light(i)],x,t_y);
p_dest++;
u += du;
v += dv;
i += di;
}
break;
case GRL_OPAQUE|GRL_LOG2:
for (; x > 0; x--) {
int k = ((fix_fint(v)<<t_wlog)+fix_fint(u))&t_mask;
*(p_dest++) = g_ltab[t_bits[k]+fix_light(i)];
// gr_fill_upixel(g_ltab[t_bits[k]+fix_light(i)],x,t_y);
u += du;
v += dv;
i += di;
}
break;
case GRL_TRANS | GRL_LOG2:
for (; x > 0; x--) {
int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0) *p_dest = g_ltab[k + fix_light(i)];
// gr_fill_upixel(g_ltab[k+fix_light(i)],x,t_y);
p_dest++;
u += du;
v += dv;
i += di;
}
break;
}
}
tli->w += tli->dw;
#if InvDiv
inv = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe((tli->left.u += tli->left.du), inv);
tli->right.u += tli->right.du;
du = fix_mul_asm_safe(tli->right.u, inv) - u;
v = fix_mul_asm_safe((tli->left.v += tli->left.dv), inv);
tli->right.v += tli->right.dv;
dv = fix_mul_asm_safe(tli->right.v, inv) - v;
i = fix_mul_asm_safe((tli->left.i += tli->left.di), inv);
tli->right.i += tli->right.di;
di = fix_mul_asm_safe(tli->right.i, inv) - i;
#else
u = fix_div((tli->left.u += tli->left.du), tli->w);
tli->right.u += tli->right.du;
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div((tli->left.v += tli->left.dv), tli->w);
tli->right.v += tli->right.dv;
dv = fix_div(tli->right.v, tli->w) - v;
i = fix_div((tli->left.i += tli->left.di), tli->w);
tli->right.i += tli->right.di;
di = fix_div(tli->right.i, tli->w) - i;
#endif
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
tli->y++;
} while (--(tli->n) > 0);
return FALSE; // tmap OK
}
void gri_trans_lit_floor_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_lit_floor_umap_loop;
tli->left_edge_func = (void (*)())gri_uviwx_edge;
tli->right_edge_func = (void (*)())gri_uviwx_edge;
}
void gri_opaque_lit_floor_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE;
}
tli->loop_func = (void (*)())gri_lit_floor_umap_loop;
tli->left_edge_func = (void (*)())gri_uviwx_edge;
tli->right_edge_func = (void (*)())gri_uviwx_edge;
}
@@ -0,0 +1,241 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8lin.c $
* $Revision: 1.11 $
* $Author: lmfeeney $
* $Date: 1994/08/12 01:09:59 $
*
* Routines for drawing fixed-point lines onto a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8lin.c $
* Revision 1.11 1994/08/12 01:09:59 lmfeeney
* get fill/solid parm from right place
*
* Revision 1.10 1994/06/11 01:22:44 lmfeeney
* guts of the routine moved to fl8{c,s}lin.h, per fill type
* line drawers are created by defining macros and including
* this file
*
* Revision 1.9 1994/05/06 18:18:58 lmfeeney
* rewritten for greater accuracy
*
* Revision 1.8 1993/12/15 11:25:22 kaboom
* Fixed up problems with not including endpoints and to match up with
* new polygon scanner.
*
* Revision 1.7 1993/10/19 09:50:35 kaboom
* Replaced #include "grd.h" with new headers split from grd.h.
*
* Revision 1.6 1993/10/08 01:15:18 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.5 1993/06/23 04:56:07 kaboom
* Put in checks for single-pixel horizontal and vertical lines.
*
* Revision 1.4 1993/06/22 15:14:38 kaboom
* Now checks to see if final span is empty.
*
* Revision 1.3 1993/06/16 18:15:24 kaboom
* Removed foolish mprintfs accidentally left in.
*
* Revision 1.2 1993/06/16 01:59:53 kaboom
* Fixed gradual precision error. Last span now explicitly set to x1
* instead of adding m_inv.
*
* Revision 1.1 1993/03/02 20:33:50 kaboom
* Initial revision
*/
#include "cnvdat.h"
#include "ctxmac.h"
#include "fill.h"
#include "fix.h"
#include "lg.h"
#include "plytyp.h"
#include "scrdat.h"
#include <string.h>
/* This particular mess implements the fix_uline for each of the
five fill types. The main driver (essentially the code in the
the 'original' fl8lin.c) is now a code fragment in fl8lin.h
For each function, four macros are (re)defined - flat8_pixel_fill_xf
and flat8_pixel_fill_xi - which set the pixel value in the case of
x fix-point and x known to be integer, and flat8_pixel_fill_row, which
allows us to retain the speed hack for a (nearly) horizontal line. For
fill types which are indep of the pixel value (norm, solid, clut), the
color is set only once in flat8_pixel_fill_init.
Note that each macro is referenced 7 times (the line drawer has
lots of dx <=> dy type cases). This makes blend come out huge.
None of these macros take arguments, instead they rely on secret
gnosis of the variable names in fl8lin.h
*/
/* not all line fill functions use all their parameters */
// MLA #pragma off (unreferenced)
/* same for norm, solid and clut */
#undef flat8_pixel_fill_xf
#define flat8_pixel_fill_xf \
do { \
p[fix_fint(x0)] = c; \
} while (0)
#undef flat8_pixel_fill_xi
#define flat8_pixel_fill_xi \
do { \
p[x0] = c; \
} while (0)
#undef flat8_pixel_fill_row
#define flat8_pixel_fill_row \
do { \
LG_memset(p + x0, c, x1 - x0 + 1); \
} while (0)
#undef flat8_pixel_fill_init
#define flat8_pixel_fill_init \
do { \
if (gr_get_fill_type() == FILL_SOLID) \
c = (uchar)parm; \
} while (0)
/* norm */
void gri_flat8_uline_ns(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8lin.h"
}
/* clut */
#undef flat8_pixel_fill_init
#define flat8_pixel_fill_init \
do { \
c = (long)(((uchar *)parm)[c]); \
} while (0)
void gri_flat8_uline_clut(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8lin.h"
}
/* xor */
#undef flat8_pixel_fill_xf
#define flat8_pixel_fill_xf \
do { \
p[fix_fint(x0)] = c ^ p[fix_fint(x0)]; \
} while (0)
#undef flat8_pixel_fill_xi
#define flat8_pixel_fill_xi \
do { \
p[x0] = c ^ p[x0]; \
} while (0)
#undef flat8_pixel_fill_row
#define flat8_pixel_fill_row \
do { \
while (x0 < x1) { \
flat8_pixel_fill_xi; \
x0++; \
} \
} while (0)
void gri_flat8_uline_xor(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8lin.h"
}
/* blend -- maybe we should just swallow the function call */
#define QMASK 0x3fc7f8ff
/* convert red in a glomped rgb to a fixed point */
#define rtof(b) (((b)&0x3ff) << 12)
/* convert green in a glomped rgb to a fixed point */
#define gtof(b) (((b)&0x1ff800) << 1)
/* convert blue in a glomped rgb to a fixed point */
#define btof(b) (((b)&0xffc00000) >> 10)
#undef flat8_pixel_fill_xf
#define flat8_pixel_fill_xf \
do { \
uchar *k; \
grs_rgb prev; \
grs_rgb lg_new; \
fix r1, g1, b1; \
\
prev = grd_bpal[p[fix_fint(x0)]]; \
lg_new = grd_bpal[c]; \
\
r1 = fix_mul(rtof(lg_new), (fix)parm) + fix_mul(rtof(prev), FIX_UNIT - (fix)parm); \
g1 = fix_mul(gtof(lg_new), (fix)parm) + fix_mul(gtof(prev), FIX_UNIT - (fix)parm); \
b1 = fix_mul(btof(lg_new), (fix)parm) + fix_mul(btof(prev), FIX_UNIT - (fix)parm); \
\
k = grd_ipal; \
k += (r1 >> 17) & 0x1f; \
k += (g1 >> 12) & 0x3e0; \
k += (b1 >> 7) & 0x7c00; \
p[fix_fint(x0)] = *k; \
} while (0)
#undef flat8_pixel_fill_xi
#define flat8_pixel_fill_xi \
do { \
uchar *k; \
grs_rgb prev; \
grs_rgb lg_new; \
fix r1, g1, b1; \
\
prev = grd_bpal[p[x0]]; \
lg_new = grd_bpal[c]; \
\
r1 = fix_mul(rtof(lg_new), (fix)parm) + fix_mul(rtof(prev), FIX_UNIT - (fix)parm); \
g1 = fix_mul(gtof(lg_new), (fix)parm) + fix_mul(gtof(prev), FIX_UNIT - (fix)parm); \
b1 = fix_mul(btof(lg_new), (fix)parm) + fix_mul(btof(prev), FIX_UNIT - (fix)parm); \
\
k = grd_ipal; \
k += (r1 >> 17) & 0x1f; \
k += (g1 >> 12) & 0x3e0; \
k += (b1 >> 7) & 0x7c00; \
p[x0] = *k; \
} while (0)
#undef flat8_pixel_fill_row
#define flat8_pixel_fill_row \
do { \
while (x0 < x1) { \
flat8_pixel_fill_xi; \
x0++; \
} \
} while (0)
#undef flat8_pixel_fill_init
#define flat8_pixel_fill_init \
do { \
; \
} while (0)
void gri_flat8_uline_blend(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8lin.h"
}
@@ -0,0 +1,194 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8lin.h $
* $Revision: 1.1 $
* $Author: lmfeeney $
* $Date: 1994/06/11 00:51:50 $
*/
/* this was originally the guts of flat8_fix_uline */
fix x0, y0, x1, y1;
fix dx, dy; /* deltas in x and y */
fix t; /* temporary fix */
uchar *p; /* pointer into canvas */
x0 = v0->x;
y0 = v0->y;
x1 = v1->x;
y1 = v1->y;
/* set endpoints
note that this cannot go negative or change octant, since the ==
case is excluded */
if (x0 < x1) {
x1 -= 1; /* e.g. - epsilon */
} else if (x0 > x1) {
x0 -= 1;
}
if (y0 < y1) {
y1 -= 1;
} else if (y0 > y1) {
y0 -= 1;
}
dx = fix_trunc(x1) - fix_trunc(x0); /* x extent in pixels, (macro is flakey) */
dx = fix_abs(dx);
dy = fix_trunc(y1) - fix_trunc(y0); /* y extent in pixels */
dy = fix_abs(dy);
if (dx == 0 && dy == 0)
return;
flat8_pixel_fill_init;
/* three cases: absolute value dx < = > dy
along the longer dimension, the fixpoint x0 (or y0) is treated
as an int
the points are swapped if needed and the rgb initial and deltas
are calculated accordingly
there are two or three sub-cases - a horizontal or vertical line,
and the dx or dy being added or subtracted. dx and dy
are kept as absolute values and +/- is managed in
two separate inner loops if it is a y change, since you need to
manage the canvas pointer
if y is being changed by 'dy' and x is being incremented, do a
FunkyBitCheck (TM) to see whether the integer part of y has changed
and if it has, resetting the the canvas pointer to the next row
if x is being changed by 'dx' and y is being incremented, just
add or subtract row to increment y in the canvas
the endpoints are walked inclusively in all cases, see above
45' degree lines are explicitly special cased -- because it
all runs as integers, but it's probably not frequent enough
to justify the check
*/
if (dx > dy) {
x0 = fix_int(x0);
x1 = fix_int(x1);
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
}
p = grd_bm.bits + grd_bm.row * (fix_int(y0));
if ((fix_int(y0)) == (fix_int(y1))) {
flat8_pixel_fill_row;
} else if (y0 < y1) {
dy = fix_div((y1 - y0), dx);
while (x0 <= x1) {
flat8_pixel_fill_xi;
x0++;
y0 += dy;
p += (grd_bm.row & (-(fix_frac(y0) < dy)));
}
} else {
dy = fix_div((y0 - y1), dx);
while (x0 <= x1) {
flat8_pixel_fill_xi;
x0++;
p -= (grd_bm.row & (-(fix_frac(y0) < dy)));
y0 -= dy;
}
}
}
else if (dy > dx) {
y0 = fix_int(y0);
y1 = fix_int(y1);
if (y0 > y1) {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
}
p = grd_bm.bits + grd_bm.row * y0;
if ((fix_int(x0)) == (fix_int(x1))) {
x0 = fix_int(x0);
while (y0 <= y1) {
flat8_pixel_fill_xi;
y0++;
p += grd_bm.row;
}
} else {
dx = fix_div((x1 - x0), dy);
while (y0 <= y1) {
flat8_pixel_fill_xf;
x0 += dx;
y0++;
p += grd_bm.row;
}
}
} else { /* dy == dx, walk the x axis, all integers */
x0 = fix_int(x0);
x1 = fix_int(x1);
y0 = fix_int(y0);
y1 = fix_int(y1);
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
}
p = grd_bm.bits + grd_bm.row * y0;
if (y0 < y1) {
while (y0 <= y1) {
flat8_pixel_fill_xi;
x0++;
y0++;
p += grd_bm.row;
}
} else {
while (y0 >= y1) {
flat8_pixel_fill_xi;
x0++;
y0--;
p -= grd_bm.row;
}
}
}
@@ -0,0 +1,333 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/genll.c $
* $Revision: 1.3 $
* $Author: kevin $
* $Date: 1994/08/16 12:50:11 $
*
* Routines to linearly texture map a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "fl8tmapdv.h"
#include "gente.h"
#include "poly.h"
#include "scrdat.h"
#include "tmapint.h"
#include "vtab.h"
int gri_lit_lin_umap_loop(grs_tmap_loop_info *tli);
// PPC specific optimized routines
/*extern "C"
{
int Handle_Lit_Lin_Loop_PPC(fix u, fix v, fix du, fix dv, fix dx,
grs_tmap_loop_info
*tli, uchar *start_pdest, uchar *t_bits, long gr_row, fix i, fix di, uchar *g_ltab, uchar t_wlog, ulong t_mask);
int Handle_TLit_Lin_Loop2_PPC(fix u, fix v, fix du, fix dv, fix dx,
grs_tmap_loop_info *tli, uchar *start_pdest, uchar *t_bits, long gr_row,
fix i, fix di, uchar *g_ltab, uchar t_wlog, ulong t_mask);
}*/
int Handle_Lit_Lin_Loop_C(fix u, fix v, fix du, fix dv, fix dx, grs_tmap_loop_info *tli, uchar *start_pdest,
uchar *t_bits, long gr_row, fix i, fix di, uchar *g_ltab, uchar t_wlog, ulong t_mask) {
int x, t_xl, t_xr, inv;
uchar *p_dest;
tli->y += tli->n;
do {
if ((x = fix_ceil(tli->right.x) - fix_ceil(tli->left.x)) > 0) {
x = fix_div(fix_make(1, 0) << 8, dx);
di = fix_mul_asm_safe_light(di, x);
x >>= 8;
du = fix_mul_asm_safe(du, x);
dv = fix_mul_asm_safe(dv, x);
x = fix_ceil(tli->left.x) - tli->left.x;
u += fix_mul(du, x);
v += fix_mul(dv, x);
i += fix_mul(di, x);
// copy out tli-> stuff into locals
t_xl = fix_cint(tli->left.x);
t_xr = fix_cint(tli->right.x);
p_dest = start_pdest + t_xl;
x = t_xr - t_xl;
for (; x > 0; x--) {
*(p_dest++) = g_ltab[t_bits[((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask] + fix_light(i)];
u += du;
v += dv;
i += di;
}
} else if (x < 0)
return TRUE; // punt this tmap
u = (tli->left.u += tli->left.du);
tli->right.u += tli->right.du;
du = tli->right.u - u;
v = (tli->left.v += tli->left.dv);
tli->right.v += tli->right.dv;
dv = tli->right.v - v;
i = (tli->left.i += tli->left.di);
tli->right.i += tli->right.di;
di = tli->right.i - i;
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
dx = tli->right.x - tli->left.x;
start_pdest += gr_row;
} while (--(tli->n) > 0);
return FALSE; // tmap OK
}
int Handle_TLit_Lin_Loop2_C(fix u, fix v, fix du, fix dv, fix dx, grs_tmap_loop_info *tli, uchar *start_pdest,
uchar *t_bits, long gr_row, fix i, fix di, uchar *g_ltab, uchar t_wlog, ulong t_mask) {
int x, k;
uchar *p_dest;
int t_xl, t_xr;
int lx, rx;
lx = tli->left.x;
rx = tli->right.x;
tli->y += tli->n;
do {
if ((x = fix_ceil(rx) - fix_ceil(lx)) > 0) {
x = fix_ceil(lx) - lx;
k = fix_div(fix_make(1, 0) << 8, dx);
di = fix_mul_asm_safe_light(di, k);
k >>= 8;
du = fix_mul_asm_safe(du, k);
dv = fix_mul_asm_safe(dv, k);
u += fix_mul(du, x);
v += fix_mul(dv, x);
i += fix_mul(di, x);
// copy out tli-> stuff into locals
t_xl = fix_cint(lx);
t_xr = fix_cint(rx);
p_dest = start_pdest + t_xl;
x = t_xr - t_xl;
for (; x > 0; x--) {
// assume pixel in transparent first
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0) // not transparent, move to assuming opaque
*p_dest = g_ltab[k + fix_light(i)];
p_dest++;
u += du;
v += dv;
i += di;
}
} else if (x < 0)
return TRUE; // punt this tmap
u = (tli->left.u += tli->left.du);
tli->right.u += tli->right.du;
du = tli->right.u - u;
v = (tli->left.v += tli->left.dv);
tli->right.v += tli->right.dv;
dv = tli->right.v - v;
i = (tli->left.i += tli->left.di);
tli->right.i += tli->right.di;
di = tli->right.i - i;
lx += tli->left.dx;
rx += tli->right.dx;
dx = rx - lx;
start_pdest += gr_row;
} while (--(tli->n) > 0);
tli->left.x = lx;
tli->right.x = rx;
return FALSE; // tmap OK
}
int gri_lit_lin_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, i, du, dv, di, dx, d;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
register int x, k;
int t_xl, t_xr, inv;
int32_t *t_vtab;
uchar *t_bits;
uchar *p_dest;
uchar temp_pix;
uchar t_wlog;
ulong t_mask;
uchar *g_ltab;
long gr_row;
uchar *start_pdest;
u = tli->left.u;
du = tli->right.u - u;
v = tli->left.v;
dv = tli->right.v - v;
i = tli->left.i;
di = tli->right.i - i;
dx = tli->right.x - tli->left.x;
t_vtab = tli->vtab;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
g_ltab = grd_screen->ltab;
t_bits = tli->bm.bits;
gr_row = grd_bm.row;
start_pdest = grd_bm.bits + (gr_row * (tli->y));
// handle optimized cases first
if (tli->bm.hlog == (GRL_OPAQUE | GRL_LOG2))
return (
Handle_Lit_Lin_Loop_C(u, v, du, dv, dx, tli, start_pdest, t_bits, gr_row, i, di, g_ltab, t_wlog, t_mask));
if (tli->bm.hlog == (GRL_TRANS | GRL_LOG2))
return (
Handle_TLit_Lin_Loop2_C(u, v, du, dv, dx, tli, start_pdest, t_bits, gr_row, i, di, g_ltab, t_wlog, t_mask));
do {
if ((d = fix_ceil(tli->right.x) - fix_ceil(tli->left.x)) > 0) {
d = fix_ceil(tli->left.x) - tli->left.x;
#if InvDiv
k = fix_div(fix_make(1, 0) << 8, dx);
di = fix_mul_asm_safe_light(di, k);
k >>= 8;
du = fix_mul_asm_safe(du, k);
dv = fix_mul_asm_safe(dv, k);
#else
du = fix_div(du, dx);
dv = fix_div(dv, dx);
di = fix_div(di, dx);
#endif
u += fix_mul(du, d);
v += fix_mul(dv, d);
i += fix_mul(di, d);
// copy out tli-> stuff into locals
t_xl = fix_cint(tli->left.x);
t_xr = fix_cint(tli->right.x);
p_dest = start_pdest + t_xl;
x = t_xr - t_xl;
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (; x > 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
*(p_dest++) =
g_ltab[t_bits[k] + fix_light(i)]; // gr_fill_upixel(g_ltab[t_bits[k]+fix_light(i)],x,t_y);
u += du;
v += dv;
i += di;
}
break;
case GRL_TRANS:
for (; x > 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0)
*p_dest = g_ltab[k + fix_light(i)]; // gr_fill_upixel(g_ltab[k+fix_light(i)],x,t_y);
p_dest++;
u += du;
v += dv;
i += di;
}
break;
// handled in special case code
case GRL_OPAQUE | GRL_LOG2:
for (; x > 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
*(p_dest++) =
g_ltab[t_bits[k] + fix_light(i)]; // gr_fill_upixel(g_ltab[t_bits[k]+fix_light(i)],x,t_y);
u += du;
v += dv;
i += di;
}
break;
case GRL_TRANS | GRL_LOG2:
for (; x > 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0)
*p_dest = g_ltab[k + fix_light(i)]; // gr_fill_upixel(g_ltab[k+fix_light(i)],x,t_y);
p_dest++;
u += du;
v += dv;
i += di;
}
break;
}
} else if (d < 0)
return TRUE; /* punt this tmap */
u = (tli->left.u += tli->left.du);
tli->right.u += tli->right.du;
du = tli->right.u - u;
v = (tli->left.v += tli->left.dv);
tli->right.v += tli->right.dv;
dv = tli->right.v - v;
i = (tli->left.i += tli->left.di);
tli->right.i += tli->right.di;
di = tli->right.i - i;
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
dx = tli->right.x - tli->left.x;
tli->y++;
start_pdest += gr_row;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
void gri_trans_lit_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_lit_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvix_edge;
tli->left_edge_func = (void (*)())gri_uvix_edge;
}
void gri_opaque_lit_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE;
}
tli->loop_func = (void (*)())gri_lit_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvix_edge;
tli->left_edge_func = (void (*)())gri_uvix_edge;
}
@@ -0,0 +1,300 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/genl.c $
* $Revision: 1.4 $
* $Author: kevin $
* $Date: 1994/08/16 12:48:26 $
*
* Routines to linearly texture map a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "fl8tmapdv.h"
#include "gente.h"
#include "poly.h"
#include "tmapint.h"
#include "vtab.h"
// prototypes
int gri_lin_umap_loop(grs_tmap_loop_info *tli);
/*extern "C"
{
int Handle_LinClut_Loop_PPC(fix u, fix v, fix du, fix dv, fix dx,
grs_tmap_loop_info
*tli, uchar *start_pdest, uchar *t_bits, int32_t gr_row, uchar *t_clut, uchar t_wlog, uint32_t t_mask);
}*/
int Handle_LinClut_Loop_C(fix u, fix v, fix du, fix dv, fix dx, grs_tmap_loop_info *tli, uchar *start_pdest,
uchar *t_bits, int32_t gr_row, uchar *t_clut, uchar t_wlog, uint32_t t_mask) {
register int x, k;
uchar *p_dest;
register fix rx, lx;
rx = tli->right.x;
lx = tli->left.x;
tli->y += tli->n;
do {
if ((x = fix_ceil(rx) - fix_ceil(lx)) > 0) {
x = fix_ceil(lx) - lx;
k = fix_div(fix_make(1, 0), dx);
du = fix_mul_asm_safe(du, k);
dv = fix_mul_asm_safe(dv, k);
u += fix_mul(du, x);
v += fix_mul(dv, x);
// copy out tli-> stuff into locals
p_dest = start_pdest + fix_cint(lx);
x = fix_cint(rx) - fix_cint(lx);
for (; x > 0; x--) {
*(p_dest++) = t_clut[t_bits[((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask]];
u += du;
v += dv;
}
} else if (x < 0)
return TRUE; // punt this tmap
u = (tli->left.u += tli->left.du);
tli->right.u += tli->right.du;
du = tli->right.u - u;
v = (tli->left.v += tli->left.dv);
tli->right.v += tli->right.dv;
dv = tli->right.v - v;
lx += tli->left.dx;
rx += tli->right.dx;
dx = rx - lx;
start_pdest += gr_row;
} while (--(tli->n) > 0);
tli->right.x = rx;
tli->left.x = lx;
return FALSE; // tmap OK
}
int gri_lin_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, du, dv, dx, d;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
register int x, k;
uchar *p_dest;
uchar temp_pix;
int32_t *t_vtab;
uchar *t_bits;
uchar *t_clut;
uchar t_wlog;
uint32_t t_mask;
int32_t gr_row;
uchar *start_pdest;
int32_t inv;
u = tli->left.u;
du = tli->right.u - u;
v = tli->left.v;
dv = tli->right.v - v;
dx = tli->right.x - tli->left.x;
t_vtab = tli->vtab;
t_clut = tli->clut;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
t_bits = tli->bm.bits;
gr_row = grd_bm.row;
start_pdest = grd_bm.bits + (gr_row * (tli->y));
// handle PowerPC loop
if (tli->bm.hlog == (GRL_OPAQUE | GRL_LOG2 | GRL_CLUT))
return (Handle_LinClut_Loop_C(u, v, du, dv, dx, tli, start_pdest, t_bits, gr_row, t_clut, t_wlog, t_mask));
do {
if ((d = fix_ceil(tli->right.x) - fix_ceil(tli->left.x)) > 0) {
d = fix_ceil(tli->left.x) - tli->left.x;
#if InvDiv
k = fix_div(fix_make(1, 0), dx);
du = fix_mul_asm_safe(du, k);
dv = fix_mul_asm_safe(dv, k);
#else
du = fix_div(du, dx);
dv = fix_div(dv, dx);
#endif
u += fix_mul(du, d);
v += fix_mul(dv, d);
// copy out tli-> stuff into locals
p_dest = start_pdest + fix_cint(tli->left.x);
x = fix_cint(tli->right.x) - fix_cint(tli->left.x);
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (; x > 0 && v >= 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
*(p_dest++) = t_bits[k]; // gr_fill_upixel(t_bits[k],x,y);
u += du;
v += dv;
}
break;
case GRL_TRANS:
for (; x > 0 && v >= 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
temp_pix = t_bits[k];
if (temp_pix != 0)
*p_dest = temp_pix; // gr_fill_upixel(t_bits[k],x,y);
p_dest++;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_LOG2:
for (; x > 0 && v >= 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
*(p_dest++) = t_bits[k]; // gr_fill_upixel(t_bits[k],x,y);
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_LOG2:
for (; x > 0 && v >= 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
temp_pix = t_bits[k];
if (temp_pix != 0)
*p_dest = temp_pix; // gr_fill_upixel(t_bits[k],x,y);
p_dest++;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_CLUT:
for (; x > 0 && v >= 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
*(p_dest++) = t_clut[t_bits[k]]; // gr_fill_upixel(tli->clut[t_bits[k]],x,y);
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_CLUT:
for (; x > 0 && v >= 0; x--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0)
*p_dest = t_clut[k]; // gr_fill_upixel(tli->clut[k],x,y);
p_dest++;
u += du;
v += dv;
}
break;
// handled in special case now
/* case GRL_OPAQUE|GRL_LOG2|GRL_CLUT:
for (; x>0; x--) {
k=((fix_fint(v)<<t_wlog)+fix_fint(u))&t_mask;
*(p_dest++) = t_clut[t_bits[k]]; //
gr_fill_upixel(tli->clut[t_bits[k]],x,y); u+=du; v+=dv;
}
break;*/
case GRL_TRANS | GRL_LOG2 | GRL_CLUT:
for (; x > 0 && v >= 0; x--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0)
*p_dest = t_clut[k]; // gr_fill_upixel(tli->clut[k],x,y);
p_dest++;
u += du;
v += dv;
}
break;
}
} else if (d < 0)
return TRUE; /* punt this tmap */
u = (tli->left.u += tli->left.du);
tli->right.u += tli->right.du;
du = tli->right.u - u;
v = (tli->left.v += tli->left.dv);
tli->right.v += tli->right.dv;
dv = tli->right.v - v;
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
dx = tli->right.x - tli->left.x;
tli->y++;
start_pdest += gr_row;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
void gri_trans_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
void gri_opaque_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE;
}
tli->loop_func = (void (*)())gri_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
void gri_trans_clut_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS | GRL_CLUT;
}
tli->loop_func = (void (*)())gri_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
void gri_opaque_clut_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
}
tli->loop_func = (void (*)())gri_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
@@ -0,0 +1,379 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8lop.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/16 12:57:18 $
*
* lit full perspective texture mapper.
* scanline processors.
*
*/
#include "cnvdat.h"
#include "fl8tmapdv.h"
#include "pertyp.h"
#include "plytyp.h"
#include "scrdat.h"
#include "tmapint.h"
// prototypes
void gri_opaque_lit_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_opaque_lit_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_opaque_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_opaque_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
void opaque_lit_per_hscan_Loop_C(int dx, fix l_du, fix l_dv, fix *pl_u, fix *pl_v, uchar **pp, fix *pl_y_fix,
int *py_cint, fix l_di, fix *pl_i, int l_u_mask, int l_v_shift, int l_v_mask,
fix l_scan_slope, uchar *bm_bits, int gr_row, uchar *ltab) {
fix l_u, l_v, l_y_fix, l_i;
int k, y_cint;
uchar *p;
l_u = *pl_u;
l_v = *pl_v;
l_y_fix = *pl_y_fix;
l_i = *pl_i;
p = *pp;
y_cint = *py_cint;
for (; dx > 0; dx--) {
k = ((l_u >> 16) & l_u_mask) + ((l_v >> l_v_shift) & l_v_mask);
k = bm_bits[k];
*(p++) = ltab[(fix_light(l_i)) + k];
k = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (k != y_cint)
p += gr_row;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
*pl_u = l_u;
*pl_v = l_v;
*pl_y_fix = l_y_fix;
*pl_i = l_i;
*pp = p;
*py_cint = y_cint;
}
void gri_opaque_lit_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
uchar *ltab = grd_screen->ltab;
int l_x, y_cint, l_u_mask, l_v_mask, l_v_shift;
fix k, l_u, l_v, l_du, l_dv, l_i, l_di, l_y_fix, l_scan_slope;
int gr_row;
uchar *bm_bits, *p;
// locals used to speed PPC code
fix test, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_xl, l_xr, l_xr0;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_xr0 = pi->xr0;
l_x = pi->x;
l_di = pi->di;
l_i = pi->i;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_y_fix = pi->y_fix;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_xl = pi->xl;
l_xr = pi->xr;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
if (l_scan_slope < 0)
gr_row = -gr_row;
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_x * l_du;
l_v += l_x * l_dv;
y_cint = fix_int(l_y_fix);
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
if (l_x < l_xl) {
test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
for (; l_x < l_xl; l_x++) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
}
k = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (k != y_cint) {
p += gr_row;
test += l_dtl;
} else
test += l_dyl;
p++;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
if (l_x < l_xr0) {
opaque_lit_per_hscan_Loop_C(l_xr0 - l_x, l_du, l_dv, &l_u, &l_v, &p, &l_y_fix, &y_cint, l_di, &l_i, l_u_mask,
l_v_shift, l_v_mask, l_scan_slope, bm_bits, gr_row, ltab);
l_x = l_xr0;
}
if (l_x < l_xr) {
test = l_x * l_dyr - y_cint * pi->dxr + pi->cr;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
for (; l_x < l_xr; l_x++) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
*p = ltab[(fix_light(l_i)) + k];
// gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
}
k = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (k != y_cint) {
p += gr_row;
test += l_dtr;
} else
test += l_dyr;
p++;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
pi->y_fix = l_y_fix;
pi->x = l_x;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
pi->di = l_di;
pi->i = l_i;
}
void opaque_lit_per_vscan_Loop_C(int dy, fix l_du, fix l_dv, fix *pl_u, fix *pl_v, uchar **pp, fix *pl_x_fix,
int *px_cint, fix l_di, fix *pl_i, int l_u_mask, int l_v_shift, int l_v_mask,
fix l_scan_slope, uchar *bm_bits, int gr_row, uchar *ltab) {
fix l_u, l_v, l_x_fix, l_i;
int k, x_cint;
uchar *p;
l_u = *pl_u;
l_v = *pl_v;
l_x_fix = *pl_x_fix;
l_i = *pl_i;
p = *pp;
x_cint = *px_cint;
for (; dy > 0; dy--) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
*p = ltab[(fix_light(l_i)) + k];
k = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (k != x_cint)
p -= (k - x_cint);
p += gr_row;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
*pl_u = l_u;
*pl_v = l_v;
*pl_x_fix = l_x_fix;
*pl_i = l_i;
*pp = p;
*px_cint = x_cint;
}
void gri_opaque_lit_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
int k, x_cint;
uchar *ltab = grd_screen->ltab;
// locals used to speed PPC code
fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr, l_i, l_di;
int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_x;
uchar *bm_bits;
uchar *p;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_di = pi->di;
l_i = pi->i;
l_dxr = pi->dxr;
l_x_fix = pi->x_fix;
l_y = pi->y;
l_yr = pi->yr;
l_yr0 = pi->yr0;
l_yl = pi->yl;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_y * l_du;
l_v += l_y * l_dv;
x_cint = fix_int(l_x_fix);
p = grd_bm.bits + x_cint + l_y * gr_row;
if (l_y < l_yl) {
fix test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
for (; l_y < l_yl; l_y++) {
if (test <= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtl;
p -= temp_x - x_cint;
} else {
test += l_dxl;
x_cint = fix_int(l_x_fix);
}
p += gr_row;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
if (l_y < l_yr0) {
opaque_lit_per_vscan_Loop_C(l_yr0 - l_y, l_du, l_dv, &l_u, &l_v, &p, &l_x_fix, &x_cint, l_di, &l_i, l_u_mask,
l_v_shift, l_v_mask, l_scan_slope, bm_bits, gr_row, ltab);
l_y = l_yr0;
}
if (l_y < l_yr) {
fix test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
p = grd_bm.bits + x_cint + l_y * gr_row;
for (; l_y < l_yr; l_y++) {
if (test >= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtr;
p -= temp_x - x_cint;
} else {
test += l_dxr;
x_cint = fix_int(l_x_fix);
}
p += gr_row;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
pi->x_fix = l_x_fix;
pi->y = l_y;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
pi->di = l_di;
pi->i = l_i;
}
extern void gri_lit_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
extern void gri_lit_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_opaque_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_lit_per_umap_hscan;
ps->scanline_func = (void (*)())gri_opaque_lit_per_umap_hscan_scanline;
}
void gri_opaque_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_lit_per_umap_vscan;
ps->scanline_func = (void (*)())gri_opaque_lit_per_umap_vscan_scanline;
}
@@ -0,0 +1,639 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8lp.c $
* $Revision: 1.23 $
* $Author: kevin $
* $Date: 1994/11/02 19:39:45 $
*
* lit full perspective texture mapper.
*
*/
// ************************************************************************************
// ************************************************************************************
//
// MLA - don't think we need to optimize this, its in C on the PC too
//
// ************************************************************************************
// ************************************************************************************
#include "cnvdat.h"
#include "pertyp.h"
#include "plytyp.h"
#define safe_fix_cint(x) ((fix_frac(x) == 0) ? (fix_int(x)) : (fix_int(x) + 1))
#define fix_16_20(a) ((a) >> 4)
/**************************************************************
Routines to scan polygon. hscan=standard horizontal scanlines.
vscan=vertical scanlines.
**************************************************************/
// prototypes
void gri_lit_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_lit_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_lit_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps) {
grs_per_info pi;
fix y_prime[10];
fix yp_left, yp_right;
fix x_left, x_right;
fix y_left, y_right;
fix dx_left, dx_right;
fix i_left, i_right;
fix di_left, di_right;
int yp_min, yp_max, yp_next;
int x_min, x_max, xr_min, xr_max, xl_min, xl_max;
int n_min, n_left, n_right;
int j;
pi.scale = grd_bm.w;
pi.scan_slope = ps->scan_slope;
pi.dp = ps->dp;
pi.clut = ps->clut;
if (fix_abs(pi.scan_slope) > FIX_UNIT)
return;
if (bm->row != 1 << (bm->wlog))
return;
if (bm->h != 1 << (bm->hlog))
return;
pi.u_mask = bm->row - 1;
pi.v_mask = (bm->h - 1) << bm->wlog;
pi.v_shift = 16 - bm->wlog;
yp_min = yp_max = fix_cint(y_prime[n_min = 0] = vpl[0]->y - fix_mul(vpl[0]->x, ps->scan_slope));
for (j = 1; j < n; j++) {
pi.yp = fix_cint(y_prime[j] = vpl[j]->y - fix_mul(vpl[j]->x, ps->scan_slope));
if (pi.yp < yp_min) {
yp_min = pi.yp;
n_min = j;
}
if (pi.yp > yp_max)
yp_max = pi.yp;
}
if (yp_max == yp_min)
return;
pi.denom = fix_16_20(ps->c + fix_mul(ps->b, y_prime[0]));
pi.u0 =
vpl[0]->u - fix_div(fix_mul(vpl[0]->x, ps->alpha_u) + fix_mul(vpl[0]->y, ps->beta_u) + ps->gamma_u, pi.denom);
pi.v0 =
vpl[0]->v - fix_div(fix_mul(vpl[0]->x, ps->alpha_v) + fix_mul(vpl[0]->y, ps->beta_v) + ps->gamma_v, pi.denom);
n_left = n_right = n_min;
pi.yp = yp_min;
while (fix_cint(y_prime[(n_left + n - 1) % n]) == pi.yp)
n_left = (n_left + n - 1) % n;
while (fix_cint(y_prime[(n_right + 1) % n]) == pi.yp)
n_right = (n_right + 1) % n;
pi.yp--;
pi.denom = fix_16_20(ps->c + pi.yp * ps->b);
pi.unum = ps->gamma_u + pi.yp * ps->beta_u;
pi.dunum = ps->alpha_u + fix_mul(ps->scan_slope, ps->beta_u);
pi.vnum = ps->gamma_v + pi.yp * ps->beta_v;
pi.dvnum = ps->alpha_v + fix_mul(ps->scan_slope, ps->beta_v);
if (n_right != n_left) {
pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
pi.x = fix_cint(vpl[n_left]->x);
pi.xl = fix_cint(vpl[n_right]->x);
if (pi.scan_slope > 0) {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
} else {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
}
if (pi.x < x_min)
pi.x = x_min;
if (pi.xl > x_max)
pi.xl = x_max;
pi.xr0 = pi.xr = pi.xl;
pi.i = vpl[n_left]->i;
if (pi.xr - pi.x)
pi.di = (vpl[n_right]->i - pi.i) / (pi.xr - pi.x);
else {
pi.di = 0x7fffffff;
if (vpl[n_right]->i - pi.i < 0)
pi.di = -pi.di;
}
pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp - 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dyl - pi.dxl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
yp_min--; /* first line already done */
}
pi.yp++;
while (pi.yp < yp_max) {
/* check left edge */
if (fix_cint(y_prime[n_left]) <= pi.yp) {
int n_prev, dyp;
fix d;
do {
if (fix_cint(y_prime[n_left]) == pi.yp)
n_prev = n_left;
if (--n_left < 0)
n_left = n - 1;
} while (fix_cint(y_prime[n_left]) <= pi.yp);
yp_left = y_prime[n_prev];
x_left = vpl[n_prev]->x;
y_left = vpl[n_prev]->y;
i_left = vpl[n_prev]->i;
dyp = fix_cint(y_prime[n_left]) - fix_cint(yp_left);
di_left = (vpl[n_left]->i - i_left) / dyp;
xl_min = fix_cint(x_left);
xl_max = fix_cint(vpl[n_left]->x);
pi.dxl = (vpl[n_left]->x - x_left) / pi.scale;
pi.dyl = (vpl[n_left]->y - y_left) / pi.scale;
pi.cl = fix_mul(pi.dxl, y_left) - fix_mul(pi.dyl, x_left);
d = pi.dyl - fix_mul(pi.dxl, pi.scan_slope);
dx_left = fix_div(pi.dxl, d);
x_left = fix_div(fix_mul(pi.dyl, x_left) + fix_mul(pi.dxl, fix_ceil(yp_left) - y_left), d);
if (xl_max < xl_min) {
fix foo = xl_min;
xl_min = xl_max;
xl_max = foo;
}
if (fix_mul(vpl[n_left]->x - FIX_UNIT, pi.dyl) - fix_mul(vpl[n_left]->y - pi.scan_slope, pi.dxl) + pi.cl <
0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dyl - pi.dxl;
else
pi.dtl = pi.dyl + pi.dxl;
yp_left = y_prime[n_left];
}
/* check right edge */
if (fix_cint(y_prime[n_right]) <= pi.yp) {
int n_prev, dyp;
fix d;
do {
if (fix_cint(y_prime[n_right]) == pi.yp)
n_prev = n_right;
if (++n_right == n)
n_right = 0;
} while (fix_cint(y_prime[n_right]) <= pi.yp);
yp_right = y_prime[n_prev];
x_right = vpl[n_prev]->x;
y_right = vpl[n_prev]->y;
i_right = vpl[n_prev]->i;
dyp = fix_cint(y_prime[n_right]) - fix_cint(yp_right);
di_right = (vpl[n_right]->i - i_right) / dyp;
xr_min = fix_cint(x_right);
xr_max = fix_cint(vpl[n_right]->x);
pi.dxr = (vpl[n_right]->x - x_right) / pi.scale;
pi.dyr = (vpl[n_right]->y - y_right) / pi.scale;
pi.cr = fix_mul(pi.dxr, y_right) - fix_mul(pi.dyr, x_right);
d = pi.dyr - fix_mul(pi.dxr, pi.scan_slope);
dx_right = fix_div(pi.dxr, d);
x_right = fix_div(fix_mul(pi.dyr, x_right) + fix_mul(pi.dxr, fix_ceil(yp_right) - y_right), d);
if (xr_max < xr_min) {
fix foo = xr_min;
xr_min = xr_max;
xr_max = foo;
}
if (fix_mul(vpl[n_right]->x - FIX_UNIT, pi.dyr) - fix_mul(vpl[n_right]->y - pi.scan_slope, pi.dxr) + pi.cr <
0) {
pi.dyr = -pi.dyr;
pi.dxr = -pi.dxr;
pi.cr = -pi.cr;
}
if (pi.scan_slope > 0)
pi.dtr = pi.dyr - pi.dxr;
else
pi.dtr = pi.dyr + pi.dxr;
yp_right = y_prime[n_right];
}
yp_next = (yp_right < yp_left) ? fix_cint(yp_right) : fix_cint(yp_left);
/* do 0th scanline if at yp_min */
if (pi.yp == yp_min) {
x_left -= dx_left;
x_right -= dx_right;
pi.yp--;
}
for (; pi.yp < yp_next; pi.yp++) {
if ((pi.yp + 1 == yp_max) && (n_left != n_right)) {
pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
pi.x = fix_cint(vpl[n_left]->x);
pi.xl = fix_cint(vpl[n_right]->x);
if (pi.scan_slope > 0) {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
} else {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
}
if (pi.x < x_min)
pi.x = x_min;
if (pi.xl > x_max)
pi.xl = x_max;
pi.xr0 = pi.xr = pi.xl;
pi.i = i_left;
if (pi.xr - pi.x)
pi.di = (i_right - pi.i) / (pi.xr - pi.x);
else {
pi.di = 0x7fffffff;
if (i_right - pi.i < 0)
pi.di = -pi.di;
}
pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp + 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dyl - pi.dxl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.yp = yp_max;
break;
}
if (dx_left > 0) {
pi.x = fix_fint(x_left);
pi.xl = fix_cint(x_left + dx_left);
} else {
pi.x = fix_fint(x_left + dx_left);
pi.xl = fix_cint(x_left);
}
if (dx_right > 0) {
pi.xr0 = fix_fint(x_right);
pi.xr = fix_cint(x_right + dx_right);
} else {
pi.xr0 = fix_fint(x_right + dx_right);
pi.xr = fix_cint(x_right);
}
if (pi.scan_slope > 0) {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
} else {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
}
if (xl_min > x_min)
x_min = xl_min;
if (xr_max < x_max)
x_max = xr_max;
if (pi.xr > x_max)
pi.xr = x_max;
if (pi.xr0 > x_max)
pi.xr0 = x_max;
if (pi.xl > pi.xr0)
pi.xl = pi.xr0;
if (pi.x < x_min)
pi.x = x_min;
pi.i = i_left;
if (pi.xr - pi.x)
pi.di = (i_right - pi.i) / (pi.xr - pi.x);
else {
pi.di = 0x7fffffff;
if (i_right - pi.i < 0)
pi.di = -pi.di;
}
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
if (pi.yp >= yp_min) {
i_left += di_left, i_right += di_right;
}
x_left += dx_left, x_right += dx_right;
pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
}
}
}
void gri_lit_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps) {
grs_per_info pi;
fix x_prime[10];
fix xp_top, xp_bot;
fix x_top, x_bot;
fix y_top, y_bot;
fix dy_top, dy_bot;
fix i_top, i_bot;
fix di_top, di_bot;
int xp_min, xp_max, xp_next;
int y_min, y_max, yr_min, yr_max, yl_min, yl_max;
int n_min, n_top, n_bot;
int j;
pi.scale = grd_bm.w;
pi.scan_slope = ps->scan_slope;
pi.dp = ps->dp;
pi.clut = ps->clut;
if (fix_abs(pi.scan_slope) >= FIX_UNIT)
return;
if (bm->row != 1 << (bm->wlog))
return;
if (bm->h != 1 << (bm->hlog))
return;
pi.u_mask = bm->row - 1;
pi.v_mask = (bm->h - 1) << bm->wlog;
pi.v_shift = 16 - bm->wlog;
xp_min = xp_max = fix_cint(x_prime[n_min = 0] = vpl[0]->x - fix_mul(vpl[0]->y, ps->scan_slope));
for (j = 1; j < n; j++) {
pi.xp = fix_cint(x_prime[j] = vpl[j]->x - fix_mul(vpl[j]->y, ps->scan_slope));
if (pi.xp < xp_min) {
xp_min = pi.xp;
n_min = j;
}
if (pi.xp > xp_max)
xp_max = pi.xp;
}
if (xp_max == xp_min)
return;
pi.denom = fix_16_20(ps->c + fix_mul(ps->a, x_prime[0]));
pi.u0 =
vpl[0]->u - fix_div(fix_mul(vpl[0]->x, ps->alpha_u) + fix_mul(vpl[0]->y, ps->beta_u) + ps->gamma_u, pi.denom);
pi.v0 =
vpl[0]->v - fix_div(fix_mul(vpl[0]->x, ps->alpha_v) + fix_mul(vpl[0]->y, ps->beta_v) + ps->gamma_v, pi.denom);
n_top = n_bot = n_min;
pi.xp = xp_min;
while (fix_cint(x_prime[(n_top + 1) % n]) == pi.xp)
n_top = (n_top + 1) % n;
while (fix_cint(x_prime[(n_bot + n - 1) % n]) == pi.xp)
n_bot = (n_bot + n - 1) % n;
pi.xp--;
pi.denom = fix_16_20(ps->c + pi.xp * ps->a);
pi.unum = ps->gamma_u + pi.xp * ps->alpha_u;
pi.dunum = ps->beta_u + fix_mul(ps->scan_slope, ps->alpha_u);
pi.vnum = ps->gamma_v + pi.xp * ps->alpha_v;
pi.dvnum = ps->beta_v + fix_mul(ps->scan_slope, ps->alpha_v);
if (n_bot != n_top) {
pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
pi.y = fix_cint(vpl[n_top]->y);
pi.yl = fix_cint(vpl[n_bot]->y);
if (pi.scan_slope > 0) {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
} else {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
}
if (pi.y < y_min)
pi.y = y_min;
if (pi.yl > y_max)
pi.yl = y_max;
pi.yr0 = pi.yr = pi.yl;
pi.i = vpl[n_top]->i;
if (pi.yr - pi.y)
pi.di = (vpl[n_bot]->i - pi.i) / (pi.yr - pi.y);
else {
pi.di = 0x7fffffff;
if (vpl[n_bot]->i - pi.i < 0)
pi.di = -pi.di;
}
pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp - 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dxl - pi.dyl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
xp_min--; /* first line already done */
}
pi.xp++;
while (pi.xp < xp_max) {
/* check top edge */
if (fix_cint(x_prime[n_top]) <= pi.xp) {
int n_prev, dxp;
fix d;
do {
if (fix_cint(x_prime[n_top]) == pi.xp)
n_prev = n_top;
if (++n_top == n)
n_top = 0;
} while (fix_cint(x_prime[n_top]) <= pi.xp);
xp_top = x_prime[n_prev];
x_top = vpl[n_prev]->x;
y_top = vpl[n_prev]->y;
i_top = vpl[n_prev]->i;
dxp = fix_cint(x_prime[n_top]) - fix_cint(xp_top);
di_top = (vpl[n_top]->i - i_top) / dxp;
yl_min = fix_cint(y_top);
yl_max = fix_cint(vpl[n_top]->y);
pi.dxl = (vpl[n_top]->x - x_top) / pi.scale;
pi.dyl = (vpl[n_top]->y - y_top) / pi.scale;
pi.cl = -fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, x_top);
d = pi.dxl - fix_mul(pi.dyl, pi.scan_slope);
dy_top = fix_div(pi.dyl, d);
y_top = fix_div(fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, fix_ceil(xp_top) - x_top), d);
if (yl_max < yl_min) {
fix foo = yl_min;
yl_min = yl_max;
yl_max = foo;
}
if (fix_mul(vpl[n_top]->y - FIX_UNIT, pi.dxl) - fix_mul(vpl[n_top]->x - pi.scan_slope, pi.dyl) + pi.cl <
0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dxl - pi.dyl;
else
pi.dtl = pi.dyl + pi.dxl;
xp_top = x_prime[n_top];
}
/* check bot edge */
if (fix_cint(x_prime[n_bot]) <= pi.xp) {
int n_prev, dxp;
fix d;
do {
if (fix_cint(x_prime[n_bot]) == pi.xp)
n_prev = n_bot;
if (--n_bot < 0)
n_bot = n - 1;
} while (fix_cint(x_prime[n_bot]) <= pi.xp);
xp_bot = x_prime[n_prev];
x_bot = vpl[n_prev]->x;
y_bot = vpl[n_prev]->y;
i_bot = vpl[n_prev]->i;
dxp = fix_cint(x_prime[n_bot]) - fix_cint(xp_bot);
di_bot = (vpl[n_bot]->i - i_bot) / dxp;
yr_min = fix_cint(y_bot);
yr_max = fix_cint(vpl[n_bot]->y);
pi.dxr = (vpl[n_bot]->x - x_bot) / pi.scale;
pi.dyr = (vpl[n_bot]->y - y_bot) / pi.scale;
pi.cr = -fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, x_bot);
d = pi.dxr - fix_mul(pi.dyr, pi.scan_slope);
dy_bot = fix_div(pi.dyr, d);
y_bot = fix_div(fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, fix_ceil(xp_bot) - x_bot), d);
if (yr_max < yr_min) {
fix foo = yr_min;
yr_min = yr_max;
yr_max = foo;
}
if (fix_mul(vpl[n_bot]->y - FIX_UNIT, pi.dxr) - fix_mul(vpl[n_bot]->x - pi.scan_slope, pi.dyr) + pi.cr <
0) {
pi.dyr = -pi.dyr;
pi.dxr = -pi.dxr;
pi.cr = -pi.cr;
}
if (pi.scan_slope > 0)
pi.dtr = pi.dxr - pi.dyr;
else
pi.dtr = pi.dyr + pi.dxr;
xp_bot = x_prime[n_bot];
}
xp_next = (xp_bot < xp_top) ? fix_cint(xp_bot) : fix_cint(xp_top);
/* do 0th scanline if at xp_min */
if (pi.xp == xp_min) {
y_top -= dy_top;
y_bot -= dy_bot;
pi.xp--;
}
for (; pi.xp < xp_next; pi.xp++) {
if ((pi.xp + 1 == xp_max) && (n_top != n_bot)) {
pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
pi.y = fix_cint(vpl[n_top]->y);
pi.yl = fix_cint(vpl[n_bot]->y);
if (pi.scan_slope > 0) {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
} else {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
}
if (pi.y < y_min)
pi.y = y_min;
if (pi.yl > y_max)
pi.yl = y_max;
pi.yr0 = pi.yr = pi.yl;
pi.i = i_top;
if (pi.yr - pi.y)
pi.di = (i_bot - pi.i) / (pi.yr - pi.y);
else {
pi.di = 0x7fffffff;
if (i_bot - pi.i < 0)
pi.di = -pi.di;
}
pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp + 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dxl - pi.dyl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.xp = xp_max;
break;
}
if (dy_top > 0) {
pi.y = fix_fint(y_top);
pi.yl = fix_cint(y_top + dy_top);
} else {
pi.y = fix_fint(y_top + dy_top);
pi.yl = fix_cint(y_top);
}
if (dy_bot > 0) {
pi.yr0 = fix_fint(y_bot);
pi.yr = fix_cint(y_bot + dy_bot);
} else {
pi.yr0 = fix_fint(y_bot + dy_bot);
pi.yr = fix_cint(y_bot);
}
if (pi.scan_slope > 0) {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
} else {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
}
if (yl_min > y_min)
y_min = yl_min;
if (yr_max < y_max)
y_max = yr_max;
if (pi.yr > y_max)
pi.yr = y_max;
if (pi.yr0 > y_max)
pi.yr0 = y_max;
if (pi.yl > pi.yr0)
pi.yl = pi.yr0;
if (pi.y < y_min)
pi.y = y_min;
pi.i = i_top;
if (pi.yr - pi.y)
pi.di = (i_bot - pi.i) / (pi.yr - pi.y);
else {
pi.di = 0x7fffffff;
if (i_bot - pi.i < 0)
pi.di = -pi.di;
}
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
if (pi.xp >= xp_min) {
i_top += di_top, i_bot += di_bot;
}
y_top += dy_top, y_bot += dy_bot;
pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
}
}
}
@@ -0,0 +1,329 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/FL8ltp.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/16 12:57:21 $
*
* lit full perspective texture mapper.
* scanline processors.
*
*/
#include "cnvdat.h"
#include "fl8tmapdv.h"
#include "pertyp.h"
#include "plytyp.h"
#include "scrdat.h"
#include "tmapint.h"
// prototypes
void gri_trans_lit_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_trans_lit_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_trans_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_trans_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_trans_lit_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, y_cint;
uchar *ltab = grd_screen->ltab;
// locals used to speed PPC code
fix test;
fix l_u, l_v, l_du, l_dv, l_y_fix, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr, l_i, l_di;
int l_x, l_xl, l_xr, l_xr0, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_y;
uchar *bm_bits, *p;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_di = pi->di;
l_i = pi->i;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_y_fix = pi->y_fix;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_xr0 = pi->xr0;
l_x = pi->x;
l_xl = pi->xl;
l_xr = pi->xr;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_x * l_du;
l_v += l_x * l_dv;
y_cint = fix_int(l_y_fix);
if (l_scan_slope < 0)
gr_row = -gr_row;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
if (l_x < l_xl) {
test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
for (; l_x < l_xl; l_x++) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
if (k)
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtl;
} else
test += l_dyl;
p++;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
for (; l_x < l_xr0; l_x++) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
if (k)
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint)
p += gr_row;
p++;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
if (l_x < l_xr) {
test = l_x * l_dyr - y_cint * pi->dxr + pi->cr;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
for (; l_x < l_xr; l_x++) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
if (k)
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtr;
} else
test += l_dyr;
p++;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
pi->y_fix = l_y_fix;
pi->x = l_x;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
pi->di = l_di;
pi->i = l_i;
}
void gri_trans_lit_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, x_cint;
uchar *ltab = grd_screen->ltab;
// locals used to speed PPC code
fix test;
fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr, l_i, l_di;
int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_x;
uchar *bm_bits;
uchar *p;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_di = pi->di;
l_i = pi->i;
l_dxr = pi->dxr;
l_x_fix = pi->x_fix;
l_y = pi->y;
l_yr = pi->yr;
l_yr0 = pi->yr0;
l_yl = pi->yl;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_y * l_du;
l_v += l_y * l_dv;
x_cint = fix_int(l_x_fix);
p = grd_bm.bits + x_cint + l_y * gr_row;
if (l_y < l_yl) {
test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
for (; l_y < l_yl; l_y++) {
if (test <= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
if (k)
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtl;
p -= (temp_x - x_cint);
} else
test += l_dxl;
p += gr_row;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
for (; l_y < l_yr0; l_y++) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
if (k)
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint)
p -= (temp_x - x_cint);
p += gr_row;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
if (l_y < l_yr) {
test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
p = grd_bm.bits + x_cint + l_y * gr_row;
for (; l_y < l_yr; l_y++) {
if (test >= 0) {
k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
k = bm_bits[k];
if (k)
*p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtr;
p -= (temp_x - x_cint);
} else
test += l_dxr;
p += gr_row;
l_u += l_du;
l_v += l_dv;
l_i += l_di;
}
}
pi->x_fix = l_x_fix;
pi->y = l_y;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
pi->di = l_di;
pi->i = l_i;
}
extern void gri_lit_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
extern void gri_lit_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_trans_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_lit_per_umap_hscan;
ps->scanline_func = (void (*)())gri_trans_lit_per_umap_hscan_scanline;
}
void gri_trans_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_lit_per_umap_vscan;
ps->scanline_func = (void (*)())gri_trans_lit_per_umap_vscan_scanline;
}
@@ -0,0 +1,381 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8lw.c $
* $Revision: 1.4 $
* $Author: kevin $
* $Date: 1994/08/16 12:50:16 $
*
* Routines to wall floor map a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "fl8tmapdv.h"
#include "gente.h"
#include "poly.h"
#include "scrmac.h"
#include "tmapint.h"
#include "vtab.h"
int gri_lit_wall_umap_loop(grs_tmap_loop_info *tli);
int gri_lit_wall_umap_loop_1D(grs_tmap_loop_info *tli);
int gri_lit_wall_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, i, du, dv, di, dy, d;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
int k, y;
uint32_t t_mask;
uint32_t t_wlog;
uchar *t_bits;
uchar *p_dest;
int32_t gr_row;
uchar *g_ltab;
fix inv_dy;
int32_t *t_vtab;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(tli->left.u, inv_dy);
du = fix_mul_asm_safe(tli->right.u, inv_dy) - u;
v = fix_mul_asm_safe(tli->left.v, inv_dy);
dv = fix_mul_asm_safe(tli->right.v, inv_dy) - v;
i = fix_mul_asm_safe(tli->left.i, inv_dy);
di = fix_mul_asm_safe(tli->right.i, inv_dy) - i;
if (di >= -256 && di <= 256)
i += 1024;
#else
u = fix_div(tli->left.u, tli->w);
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div(tli->left.v, tli->w);
dv = fix_div(tli->right.v, tli->w) - v;
i = fix_div(tli->left.i, tli->w);
di = fix_div(tli->right.i, tli->w) - i;
if (di >= -256 && di <= 256)
i += 1024;
#endif
dy = tli->right.y - tli->left.y;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
g_ltab = grd_screen->ltab;
t_vtab = tli->vtab;
t_bits = tli->bm.bits;
gr_row = grd_bm.row;
do {
if ((d = fix_ceil(tli->right.y) - fix_ceil(tli->left.y)) > 0) {
d = fix_ceil(tli->left.y) - tli->left.y;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0) << 8, dy);
di = fix_mul_asm_safe_light(di, inv_dy);
inv_dy >>= 8;
du = fix_mul_asm_safe(du, inv_dy);
dv = fix_mul_asm_safe(dv, inv_dy);
#else
du = fix_div(du, dy);
dv = fix_div(dv, dy);
di = fix_div(di, dy);
#endif
u += fix_mul(du, d);
v += fix_mul(dv, d);
i += fix_mul(di, d);
y = fix_cint(tli->right.y) - fix_cint(tli->left.y);
p_dest = grd_bm.bits + (gr_row * fix_cint(tli->left.y)) + tli->x;
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (; y > 0; y--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
*p_dest = g_ltab[t_bits[k] + fix_light(i)]; // gr_fill_upixel(g_ltab[t_bits[k]+fix_light(i)],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
i += di;
}
break;
case GRL_TRANS:
for (; y > 0; y--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0)
*p_dest = g_ltab[k + fix_light(i)]; // gr_fill_upixel(g_ltab[k+fix_light(i)],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
i += di;
}
break;
case GRL_OPAQUE | GRL_LOG2:
for (; y > 0; y--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
*p_dest = g_ltab[t_bits[k] + fix_light(i)];
p_dest += gr_row;
u += du;
v += dv;
i += di;
}
break;
case GRL_TRANS | GRL_LOG2:
for (; y > 0; y--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0)
*p_dest = g_ltab[k + fix_light(i)]; // gr_fill_upixel(g_ltab[k+fix_light(i)],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
i += di;
}
break;
}
} else if (d < 0)
return TRUE; /* punt this tmap */
tli->w += tli->dw;
// figure out new left u & v & i
inv_dy = 0;
k = tli->left.u + tli->left.du;
y = tli->left.v + tli->left.dv;
tli->left.i += tli->left.di;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(k, inv_dy);
v = fix_mul_asm_safe(y, inv_dy);
i = fix_mul_asm_safe(tli->left.i, inv_dy);
if (di >= -256 && di <= 256)
i += 1024;
#else
u = fix_div(k, tli->w);
v = fix_div(y, tli->w);
i = fix_div(tli->left.i, tli->w);
if (di >= -256 && di <= 256)
i += 1024;
#endif
tli->left.u = k;
tli->left.v = y;
// figure out new right u & v & i
k = tli->right.u + tli->right.du;
y = tli->right.v + tli->right.dv;
tli->right.i += tli->right.di;
#if InvDiv
du = fix_mul_asm_safe(k, inv_dy) - u;
dv = fix_mul_asm_safe(y, inv_dy) - v;
di = fix_mul_asm_safe(tli->right.i, inv_dy) - i;
#else
du = fix_div(k, tli->w) - u;
dv = fix_div(y, tli->w) - v;
di = fix_div(tli->right.i, tli->w) - i;
#endif
tli->right.u = k;
tli->right.v = y;
tli->left.y += tli->left.dy;
tli->right.y += tli->right.dy;
dy = tli->right.y - tli->left.y;
tli->x++;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
void gri_trans_lit_wall_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_lit_wall_umap_loop;
tli->left_edge_func = (void (*)())gri_uviwy_edge;
tli->right_edge_func = (void (*)())gri_uviwy_edge;
}
void gri_opaque_lit_wall_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE;
}
tli->loop_func = (void (*)())gri_lit_wall_umap_loop;
tli->left_edge_func = (void (*)())gri_uviwy_edge;
tli->right_edge_func = (void (*)())gri_uviwy_edge;
}
/*extern "C"
{
extern int HandleWallLitLoop1D_PPC(grs_tmap_loop_info *tli,
fix u, fix v, fix i, fix dv, fix di, fix dy,
uchar *g_ltab, int32_t *t_vtab, uchar *o_bits,
int32_t gr_row, uint32_t t_mask, uint32_t t_wlog);
}*/
int HandleWallLitLoop1D_C(grs_tmap_loop_info *tli, fix u, fix v, fix i, fix dv, fix di, fix dy, uchar *g_ltab,
uchar *o_bits, int32_t gr_row, uint32_t t_mask, uint32_t t_wlog) {
fix d, inv_dy;
register fix lefty, righty;
int32_t k, y;
uchar *t_bits;
uchar *p_dest;
lefty = tli->left.y;
righty = tli->right.y;
do {
if ((d = fix_ceil(righty) - fix_ceil(lefty)) > 0) {
d = fix_ceil(lefty) - lefty;
inv_dy = fix_div(fix_make(1, 0) << 8, dy);
dv = fix_mul_asm_safe(dv, inv_dy >> 8);
di = fix_mul_asm_safe_light(di, inv_dy);
v += fix_mul(dv, d);
i += fix_mul(di, d);
if (di >= -256 && di <= 256)
i += 256;
y = fix_cint(righty) - fix_cint(lefty);
p_dest = grd_bm.bits + (gr_row * fix_cint(lefty)) + tli->x;
t_bits = o_bits + fix_fint(u);
// inner loop
for (; y > 0; y--) {
k = (fix_fint(v) << t_wlog) & t_mask;
*p_dest = g_ltab[t_bits[k] + fix_light(i)];
p_dest += gr_row;
v += dv;
i += di;
}
} else if (d < 0)
return TRUE; // punt this tmap
tli->w += tli->dw;
// figure out new left u & v & i
k = tli->left.u + tli->left.du;
y = tli->left.v + tli->left.dv;
tli->left.i += tli->left.di;
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(k, inv_dy);
v = fix_mul_asm_safe(y, inv_dy);
i = fix_mul_asm_safe(tli->left.i, inv_dy);
tli->left.u = k;
tli->left.v = y;
// figure out new right u & v & i
k = tli->right.u + tli->right.du;
y = tli->right.v + tli->right.dv;
tli->right.i += tli->right.di;
dv = fix_mul_asm_safe(y, inv_dy) - v;
di = fix_mul_asm_safe(tli->right.i, inv_dy) - i;
if (di >= -256 && di <= 256)
i += 1024;
tli->right.u = k;
tli->right.v = y;
lefty += tli->left.dy;
righty += tli->right.dy;
dy = righty - lefty;
tli->x++;
} while (--(tli->n) > 0);
tli->left.y = lefty;
tli->right.y = righty;
return FALSE; // tmap OK
}
// ==================================================================================
// Wall_1D versions of routines
int gri_lit_wall_umap_loop_1D(grs_tmap_loop_info *tli) {
fix u, v, i, dv, di, dy;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
int k, y;
uint32_t t_mask;
uint32_t t_wlog;
int32_t gr_row;
uchar *g_ltab;
uchar *o_bits;
fix inv_dy;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(tli->left.u, inv_dy);
v = fix_mul_asm_safe(tli->left.v, inv_dy);
dv = fix_mul_asm_safe(tli->right.v, inv_dy) - v;
i = fix_mul_asm_safe(tli->left.i, inv_dy);
di = fix_mul_asm_safe(tli->right.i, inv_dy) - i;
if (di >= -256 && di <= 256)
i += 512;
#else
u = fix_div(tli->left.u, tli->w);
v = fix_div(tli->left.v, tli->w);
dv = fix_div(tli->right.v, tli->w) - v;
i = fix_div(tli->left.i, tli->w);
di = fix_div(tli->right.i, tli->w) - i;
if (di >= -256 && di <= 256)
i += 512;
#endif
dy = tli->right.y - tli->left.y;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
g_ltab = grd_screen->ltab;
o_bits = tli->bm.bits;
gr_row = grd_bm.row;
return HandleWallLitLoop1D_C(tli, u, v, i, dv, di, dy, g_ltab, o_bits, gr_row, t_mask, t_wlog);
}
void gri_opaque_lit_wall1d_umap_init(grs_tmap_loop_info *tli) {
// Wall1D is always log2
/* if ((tli->bm.row==(1<<tli->bm.wlog)) &&
(tli->bm.h==(1<<tli->bm.hlog))) {*/
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
/* } else {
tli->vtab=gr_make_vtab(&(tli->bm));
tli->bm.hlog=GRL_OPAQUE;
}*/
tli->loop_func = (void (*)())gri_lit_wall_umap_loop_1D;
tli->left_edge_func = (void (*)())gri_uviwy_edge;
tli->right_edge_func = (void (*)())gri_uviwy_edge;
}
@@ -0,0 +1,105 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8mono.c $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:39 $
*
* Routines for drawing monochrome bitmaps into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8mono.c $
* Revision 1.3 1993/10/19 09:50:39 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/08 01:15:23 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.1 1993/02/16 14:15:56 kaboom
* Initial revision
*
********************************************************************
* Log from old flat8.c:
*
* Revision 1.5 1992/12/11 13:13:33 kaboom
* Fixed bug in transparent case of flat8_mono_ubitmap -- destination
* pointer wasn't getting incremented on transparent pixels.
*/
#include "bit.h"
#include "bitmap.h"
#include "cnvdat.h"
void flat8_mono_ubitmap(grs_bitmap *bm, short x, short y) {
short w, h; /* working width and height */
int bit; /* bit from 0-7 in source byte */
uchar *p_row; /* pointer to current row of bitmap */
uchar *p_src; /* pointer to source byte */
uchar *p_dst;
h = bm->h;
p_row = bm->bits;
p_dst = grd_bm.bits + y * grd_bm.row + x;
if (bm->flags & BMF_TRANS) {
/* transparent bitmap; draw 1's as fcolor, don't draw 0's. */
while (h-- > 0) {
/* set up scanline. */
bit = bm->align;
p_src = p_row;
w = bm->w;
while (w-- > 0) {
/* do current scanline. */
if (*p_src & bitmask[bit])
*p_dst++ = grd_gc.fcolor;
else
p_dst++;
if (++bit > 7) {
bit = 0;
p_src++;
}
}
p_dst += grd_bm.row - bm->w;
p_row += bm->row;
}
} else {
/* opaque bitmap; draw 1's as fcolor, 0's as bcolor. */
while (h-- > 0) {
bit = bm->align;
p_src = p_row;
w = bm->w;
while (w-- > 0) {
if (*p_src & bitmask[bit])
*p_dst++ = grd_gc.fcolor;
else
*p_dst++ = grd_gc.bcolor;
if (++bit > 7) {
bit = 0;
p_src++;
}
}
p_dst += grd_bm.row - bm->w;
p_row += bm->row;
}
}
}
@@ -0,0 +1,183 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/* $Source: n:/project/lib/src/2d/RCS/fl8mscl.c $
* $Revision: 1.1 $
* $Author: lmfeeney $
* $Date: 1994/04/09 00:18:42 $
*/
#include "bit.h"
#include "bitmap.h"
#include "clpcon.h"
#include "cnvdat.h"
void flat8_mono_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h) {
fix x_scale; /* x scale factor */
fix y_scale; /* y scale factor */
fix x_src; /* fractional x in source bitmap */
fix y_src; /* y */
uchar *p_src; /* pointer into source bitmap */
uchar *p_dst; /* pointer into destination bitmap */
int index, bit; /* calculate indexes into char and bitmap */
int i;
/* if either width or height is to be 0, no problem. */
if (w == 0 || h == 0)
return;
x_scale = (bm->w << 16) / w;
y_scale = (bm->h << 16) / h;
y_src = y_scale >> 1;
p_dst = grd_bm.bits + y * grd_bm.row + x;
if (bm->flags & BMF_TRANS)
while (h-- > 0) {
p_src = bm->bits + fix_int(y_src) * bm->row;
x_src = (bm->align << 16) + (x_scale >> 1);
for (i = 0; i < w; i++) {
index = x_src >> (16 + 3);
bit = (x_src >> 16) & 0x0007;
if (p_src[index] & bitmask[bit])
*p_dst++ = grd_gc.fcolor;
else
p_dst++;
x_src += x_scale;
}
p_dst += grd_bm.row - w;
y_src += y_scale;
}
else
while (h-- > 0) {
p_src = bm->bits + fix_int(y_src) * bm->row;
x_src = (bm->align << 16) + (x_scale >> 4);
for (i = 0; i < w; i++) {
index = x_src >> (16 + 3);
bit = (x_src >> 16) & 0x0007;
if (p_src[index] & bitmask[bit])
*p_dst++ = grd_gc.fcolor;
else
*p_dst++ = grd_gc.bcolor;
x_src += x_scale;
}
p_dst += grd_bm.row - w;
y_src += y_scale;
}
}
int flat8_mono_scale_bitmap(grs_bitmap *bm, short x, short y, short w, short h) {
fix x_left;
fix x_scale; /* x scale factor */
fix y_scale; /* y scale factor */
fix x_src; /* fractional x in source bitmap */
fix y_src; /* y */
uchar *p_src; /* pointer into source bitmap */
uchar *p_dst;
int code;
int index = 0, bit = 0; /* char, bit in char in bitmask */
int i;
/* if either width or height is to be 0, no problem. */
if (w == 0 || h == 0)
return CLIP_ALL;
/* check for trivial reject clip. */
if (x > grd_clip.right || x + w <= grd_clip.left || y > grd_clip.bot || y + h <= grd_clip.top)
return CLIP_ALL;
x_scale = (bm->w << 16) / w;
y_scale = (bm->h << 16) / h;
x_left = y_src = 0;
code = CLIP_NONE;
if (x < grd_clip.left) {
x_left = x_scale * (grd_clip.left - x);
w -= grd_clip.left - x;
x = grd_clip.left;
code |= CLIP_LEFT;
}
if (x + w > grd_clip.right) {
w = grd_clip.right - x;
code |= CLIP_RIGHT;
}
if (y < grd_clip.top) {
y_src = y_scale * (grd_clip.top - y);
h -= grd_clip.top - y;
y = grd_clip.top;
code |= CLIP_TOP;
}
if (y + h > grd_clip.bot) {
h = grd_clip.bot - y;
code |= CLIP_BOT;
}
x_left += (bm->align << 16);
x_left += (x_scale >> 1);
y_src += y_scale >> 1;
p_dst = grd_bm.bits + y * grd_bm.row + x;
if (bm->flags & BMF_TRANS)
while (h-- > 0) {
p_src = bm->bits + fix_int(y_src) * bm->row;
x_src = x_left;
for (i = w; i > 0; i--) {
index = x_src >> (16 + 3);
bit = (x_src >> 16) & 0x0007;
if (p_src[index] & bitmask[bit])
*p_dst++ = grd_gc.fcolor;
else
p_dst++;
x_src += x_scale;
}
p_dst += grd_bm.row - w;
y_src += y_scale;
}
else
while (h-- > 0) {
p_src = bm->bits + fix_int(y_src) * bm->row;
x_src = x_left;
for (i = w; i > 0; i--) {
if (p_src[index] & bitmask[bit])
*p_dst++ = grd_gc.fcolor;
else
*p_dst++ = grd_gc.bcolor;
x_src += x_scale;
}
p_dst += grd_bm.row - w;
y_src += y_scale;
}
return code;
}
@@ -0,0 +1,237 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8nl.c $
* $Revision: 1.3 $
* $Author: kevin $
* $Date: 1994/08/16 13:12:41 $
*
* Routines to linearly texture map a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "fl8tmapdv.h"
#include "gente.h"
#include "plytyp.h"
#include "poly.h"
#include "tlucdat.h"
#include "tmapint.h"
#include "vtab.h"
// prototypes
int gri_tluc8_lin_umap_loop(grs_tmap_loop_info *tli);
int gri_tluc8_lin_umap_loop(grs_tmap_loop_info *tli)
{
fix u = tli->left.u, du = tli->right.u - u;
fix v = tli->left.v, dv = tli->right.v - v;
int32_t *t_vtab = tli->vtab;
uchar *t_bits = tli->bm.bits;
uchar *t_clut = tli->clut;
uint32_t t_mask = tli->mask;
uchar t_wlog = tli->bm.wlog;
uchar temp_pix;
while (tli->n)
{
fix dx = tli->right.x - tli->left.x;
if (dx <= 0) return TRUE; //might divide by zero below; punt this tmap
uchar *p = tli->d + fix_cint(tli->left.x);
uchar *p_final = tli->d + fix_cint(tli->right.x);
du = fix_div(du, dx);
dv = fix_div(dv, dx);
switch (tli->bm.hlog)
{
case GRL_OPAQUE:
for (; p < p_final; p++)
{
int k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
u += du;
v += dv;
}
break;
case GRL_TRANS:
for (; p < p_final; p++)
{
int k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0) {
if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
}
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_LOG2:
for (; p < p_final; p++)
{
int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_LOG2:
for (; p < p_final; p++)
{
int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0) {
if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
}
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_CLUT:
for (; p < p_final; p++)
{
int k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_CLUT:
for (; p < p_final; p++)
{
int k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0) {
if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
}
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_LOG2 | GRL_CLUT:
for (; p < p_final; p++)
{
int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_LOG2 | GRL_CLUT:
for (; p < p_final; p++)
{
int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0) {
if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
}
u += du;
v += dv;
}
break;
}
u = (tli->left.u += tli->left.du);
tli->right.u += tli->right.du;
du = tli->right.u - u;
v = (tli->left.v += tli->left.dv);
tli->right.v += tli->right.dv;
dv = tli->right.v - v;
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
tli->d += grd_bm.row;
tli->n --;
}
return FALSE; //tmap OK
}
void gri_tluc8_trans_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
void gri_tluc8_opaque_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE;
}
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
void gri_tluc8_trans_clut_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS | GRL_CLUT;
}
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
void gri_tluc8_opaque_clut_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
}
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
@@ -0,0 +1,139 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8ns.c $
* $Revision: 1.1 $
* $Author: kevin $
* $Date: 1994/08/16 13:13:12 $
*
* Routines to scale a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "gente.h"
#include "grnull.h"
#include "poly.h"
#include "tlucdat.h"
#include "tmapint.h"
// prototypes
int gri_tluc8_scale_umap_loop(grs_tmap_loop_info *tli);
int gri_tluc8_scale_umap_loop(grs_tmap_loop_info *tli) {
fix u, ul, du;
uchar *pl, *pr;
pl = tli->d + fix_cint(tli->left.x);
pr = tli->d + fix_cint(tli->right.x);
if (pr <= pl)
return TRUE;
ul = tli->left.u;
du = fix_div(tli->right.u - ul, tli->right.x - tli->left.x);
ul += fix_mul(du, fix_ceil(tli->left.x) - tli->left.x);
do {
uchar *p_dst, k;
uchar *p_src = tli->bm.bits + tli->bm.row * fix_int(tli->left.v);
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (p_dst = pl, u = ul; p_dst < pr; p_dst++) {
k = p_src[fix_fint(u)];
if (tluc8tab[k] != NULL)
*p_dst = tluc8tab[k][*p_dst];
else
*p_dst = k;
u += du;
}
break;
case GRL_TRANS:
for (p_dst = pl, u = ul; p_dst < pr; p_dst++) {
k = p_src[fix_fint(u)];
if (k != 0) {
if (tluc8tab[k] != NULL)
*p_dst = tluc8tab[k][*p_dst];
else
*p_dst = k;
}
u += du;
}
break;
case GRL_OPAQUE | GRL_CLUT:
for (p_dst = pl, u = ul; p_dst < pr; p_dst++) {
k = p_src[fix_fint(u)];
if (tluc8tab[k] != NULL)
*p_dst = tli->clut[tluc8tab[k][*p_dst]];
else
*p_dst = tli->clut[k];
u += du;
}
break;
case GRL_TRANS | GRL_CLUT:
for (p_dst = pl, u = ul; p_dst < pr; p_dst++) {
k = p_src[fix_fint(u)];
if (k != 0) {
if (tluc8tab[k] != NULL)
*p_dst = tli->clut[tluc8tab[k][*p_dst]];
else
*p_dst = tli->clut[k];
}
u += du;
}
break;
}
tli->left.v += tli->left.dv;
pl += grd_bm.row;
pr += grd_bm.row;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
void gri_tluc8_trans_scale_umap_init(grs_tmap_loop_info *tli) {
tli->bm.hlog = GRL_TRANS;
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_scale_umap_loop;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
}
void gri_tluc8_opaque_scale_umap_init(grs_tmap_loop_info *tli) {
tli->bm.hlog = GRL_OPAQUE;
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_scale_umap_loop;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
}
void gri_tluc8_trans_clut_scale_umap_init(grs_tmap_loop_info *tli) {
tli->bm.hlog = GRL_TRANS | GRL_CLUT;
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_scale_umap_loop;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
}
void gri_tluc8_opaque_clut_scale_umap_init(grs_tmap_loop_info *tli) {
tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
tli->d = grd_bm.bits + grd_bm.row * tli->y;
tli->loop_func = (void (*)())gri_tluc8_scale_umap_loop;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
}
@@ -0,0 +1,118 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8ntrp2.c $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 09:54:21 $
*
* Routine for scaling up by 2 with interpolation onto a gen canvas
*
* This file is part of the 2d library.
*
* $Log: fl8ntrp2.c $
* Revision 1.4 1993/10/19 09:54:21 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/08 01:15:24 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.2 1993/10/02 00:37:56 kaboom
* Fixed bug---wasn't drawing the last line.
*
* Revision 1.1 1993/08/05 20:06:42 jaemz
* Initial revision
*/
#include "bitmap.h"
#include "cnvdat.h"
#include "scrdat.h"
/* Assumes bm is flat, assumes canvas is big enough to
hold it, as it is, unclipped */
void flat8_interp2_ubitmap(grs_bitmap *bm) {
grs_rgb a, b;
int i, j;
uchar *c;
uchar *src, *dst;
int dd, ds;
/* Cycle through rows and do horizontal strips */
dd = 2 * grd_bm.row - grd_bm.w;
ds = bm->row - bm->w;
dst = grd_bm.bits;
src = bm->bits;
for (j = bm->h; j > 0; j--) {
for (i = bm->w; i > 0; i--) {
a = *src;
src++;
b = *src;
*dst = a;
dst++;
/* load them with the rgb values */
a = grd_bpal[a];
b = grd_bpal[b];
a = (a >> 1) + (b >> 1);
c = grd_ipal;
a = a >> 5;
c += a & 0x1f;
a = a >> 6;
c += a & 0x3e0;
a = a >> 6;
c += a & 0x7c00;
*dst = *c;
dst++;
}
dst += dd;
src += ds;
}
/* Cycle through rows and fill in missing strips */
src = grd_bm.bits;
for (i = (bm->w) * 2 - 1; i >= 0; i--) {
src = grd_bm.bits + i;
for (j = bm->h; j > 1; j--) {
a = *src;
src += 2 * grd_bm.row;
b = *src;
src -= grd_bm.row;
a = grd_bpal[a];
b = grd_bpal[b];
a = (a >> 1) + (b >> 1);
c = grd_ipal;
a = a >> 5;
c += a & 0x1f;
a = a >> 6;
c += a & 0x3e0;
a = a >> 6;
c += a & 0x7c00;
*src = *c;
src += grd_bm.row;
}
src += grd_bm.row;
*src = 0;
}
}
+571
View File
@@ -0,0 +1,571 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8p.c $
* $Revision: 1.15 $
* $Author: kevin $
* $Date: 1994/11/02 19:38:32 $
*
* full perspective texture mapper.
*
*/
// ************************************************************************************
// ************************************************************************************
//
// MLA - don't think we need to optimize this, its in C on the PC too
//
// ************************************************************************************
// ************************************************************************************
#include "cnvdat.h"
#include "pertyp.h"
#include "plytyp.h"
#define safe_fix_cint(x) ((fix_frac(x) == 0) ? (fix_int(x)) : (fix_int(x) + 1))
#define fix_16_20(a) ((a) >> 4)
// prototypes
void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
/**************************************************************
Routines to scan polygon. hscan=standard horizontal scanlines.
vscan=vertical scanlines.
**************************************************************/
void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps) {
grs_per_info pi;
fix y_prime[10];
fix yp_left, yp_right;
fix x_left, x_right;
fix y_left, y_right;
fix dx_left, dx_right;
int yp_min, yp_max, yp_next;
int x_min, x_max, xr_min, xr_max, xl_min, xl_max;
int n_min, n_left, n_right;
int j;
pi.scale = grd_bm.w;
pi.scan_slope = ps->scan_slope;
pi.dp = ps->dp;
pi.clut = ps->clut;
if (fix_abs(pi.scan_slope) > FIX_UNIT)
return;
if (bm->row != 1 << (bm->wlog))
return;
if (bm->h != 1 << (bm->hlog))
return;
pi.u_mask = bm->row - 1;
pi.v_mask = (bm->h - 1) << bm->wlog;
pi.v_shift = 16 - bm->wlog;
n_min = 0;
y_prime[n_min] = vpl[n_min]->y - fix_mul(vpl[n_min]->x, ps->scan_slope);
yp_min = yp_max = fix_cint(y_prime[n_min]);
for (j = 1; j < n; j++) {
y_prime[j] = vpl[j]->y - fix_mul(vpl[j]->x, ps->scan_slope);
pi.yp = fix_cint(y_prime[j]);
if (pi.yp < yp_min) {
yp_min = pi.yp;
n_min = j;
}
if (pi.yp > yp_max)
yp_max = pi.yp;
}
if (yp_max == yp_min)
return;
pi.denom = fix_16_20(ps->c + fix_mul(ps->b, y_prime[0]));
pi.u0 =
vpl[0]->u - fix_div(fix_mul(vpl[0]->x, ps->alpha_u) + fix_mul(vpl[0]->y, ps->beta_u) + ps->gamma_u, pi.denom);
pi.v0 =
vpl[0]->v - fix_div(fix_mul(vpl[0]->x, ps->alpha_v) + fix_mul(vpl[0]->y, ps->beta_v) + ps->gamma_v, pi.denom);
n_left = n_right = n_min;
pi.yp = yp_min;
while (fix_cint(y_prime[(n_left + n - 1) % n]) == pi.yp)
n_left = (n_left + n - 1) % n;
while (fix_cint(y_prime[(n_right + 1) % n]) == pi.yp)
n_right = (n_right + 1) % n;
pi.yp--;
pi.denom = fix_16_20(ps->c + pi.yp * ps->b);
pi.unum = ps->gamma_u + ps->beta_u * pi.yp;
pi.dunum = ps->alpha_u + fix_mul(ps->scan_slope, ps->beta_u);
pi.vnum = ps->gamma_v + ps->beta_v * pi.yp;
pi.dvnum = ps->alpha_v + fix_mul(ps->scan_slope, ps->beta_v);
if (n_right != n_left) {
pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
pi.x = fix_cint(vpl[n_left]->x);
pi.xl = fix_cint(vpl[n_right]->x);
if (pi.scan_slope > 0) {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
} else {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
}
if (pi.x < x_min)
pi.x = x_min;
if (pi.xl > x_max)
pi.xl = x_max;
pi.xr0 = pi.xr = pi.xl;
pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp - 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dyl - pi.dxl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
yp_min--; /* first line already done */
}
pi.yp++;
while (pi.yp < yp_max) {
/* check left edge */
if (fix_cint(y_prime[n_left]) <= pi.yp) {
int n_prev;
fix d;
do {
if (fix_cint(y_prime[n_left]) == pi.yp)
n_prev = n_left;
if (--n_left < 0)
n_left = n - 1;
} while (fix_cint(y_prime[n_left]) <= pi.yp);
yp_left = y_prime[n_prev];
x_left = vpl[n_prev]->x;
y_left = vpl[n_prev]->y;
xl_min = fix_cint(x_left);
xl_max = fix_cint(vpl[n_left]->x);
pi.dxl = (vpl[n_left]->x - x_left) / pi.scale;
pi.dyl = (vpl[n_left]->y - y_left) / pi.scale;
pi.cl = fix_mul(pi.dxl, y_left) - fix_mul(pi.dyl, x_left);
d = pi.dyl - fix_mul(pi.dxl, pi.scan_slope);
dx_left = fix_div(pi.dxl, d);
x_left = fix_div(fix_mul(pi.dyl, x_left) + fix_mul(pi.dxl, fix_ceil(yp_left) - y_left), d);
if (xl_max < xl_min) {
fix foo = xl_min;
xl_min = xl_max;
xl_max = foo;
}
if (fix_mul(vpl[n_left]->x - FIX_UNIT, pi.dyl) - fix_mul(vpl[n_left]->y - pi.scan_slope, pi.dxl) + pi.cl <
0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dyl - pi.dxl;
else
pi.dtl = pi.dyl + pi.dxl;
yp_left = y_prime[n_left];
}
/* check right edge */
if (fix_cint(y_prime[n_right]) <= pi.yp) {
int n_prev;
fix d;
do {
if (fix_cint(y_prime[n_right]) == pi.yp)
n_prev = n_right;
if (++n_right == n)
n_right = 0;
} while (fix_cint(y_prime[n_right]) <= pi.yp);
yp_right = y_prime[n_prev];
x_right = vpl[n_prev]->x;
y_right = vpl[n_prev]->y;
xr_min = fix_cint(x_right);
xr_max = fix_cint(vpl[n_right]->x);
pi.dxr = (vpl[n_right]->x - x_right) / pi.scale;
pi.dyr = (vpl[n_right]->y - y_right) / pi.scale;
pi.cr = fix_mul(pi.dxr, y_right) - fix_mul(pi.dyr, x_right);
d = pi.dyr - fix_mul(pi.dxr, pi.scan_slope);
dx_right = fix_div(pi.dxr, d);
x_right = fix_div(fix_mul(pi.dyr, x_right) + fix_mul(pi.dxr, fix_ceil(yp_right) - y_right), d);
if (xr_max < xr_min) {
fix foo = xr_min;
xr_min = xr_max;
xr_max = foo;
}
if (fix_mul(vpl[n_right]->x - FIX_UNIT, pi.dyr) - fix_mul(vpl[n_right]->y - pi.scan_slope, pi.dxr) + pi.cr <
0) {
pi.dyr = -pi.dyr;
pi.dxr = -pi.dxr;
pi.cr = -pi.cr;
}
if (pi.scan_slope > 0)
pi.dtr = pi.dyr - pi.dxr;
else
pi.dtr = pi.dyr + pi.dxr;
yp_right = y_prime[n_right];
}
yp_next = (yp_right < yp_left) ? fix_cint(yp_right) : fix_cint(yp_left);
/* do 0th scanline if at yp_min */
if (pi.yp == yp_min) {
x_left -= dx_left;
x_right -= dx_right;
pi.yp--;
}
for (; pi.yp < yp_next; pi.yp++) {
if ((pi.yp + 1 == yp_max) && (n_left != n_right)) {
pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
pi.x = fix_cint(vpl[n_left]->x);
pi.xl = fix_cint(vpl[n_right]->x);
if (pi.scan_slope > 0) {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
} else {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
}
if (pi.x < x_min)
pi.x = x_min;
if (pi.xl > x_max)
pi.xl = x_max;
pi.xr0 = pi.xr = pi.xl;
pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp + 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dyl - pi.dxl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.yp = yp_max;
break;
}
if (dx_left > 0) {
pi.x = fix_fint(x_left);
pi.xl = fix_cint(x_left + dx_left);
} else {
pi.x = fix_fint(x_left + dx_left);
pi.xl = fix_cint(x_left);
}
if (dx_right > 0) {
pi.xr0 = fix_fint(x_right);
pi.xr = fix_cint(x_right + dx_right);
} else {
pi.xr0 = fix_fint(x_right + dx_right);
pi.xr = fix_cint(x_right);
}
if (pi.scan_slope > 0) {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
} else {
x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
}
if (xl_min > x_min)
x_min = xl_min;
if (xr_max < x_max)
x_max = xr_max;
if (pi.xr > x_max)
pi.xr = x_max;
if (pi.xr0 > x_max)
pi.xr0 = x_max;
if (pi.xl > pi.xr0)
pi.xl = pi.xr0;
if (pi.x < x_min)
pi.x = x_min;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
x_left += dx_left, x_right += dx_right;
pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
}
}
}
void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps) {
grs_per_info pi;
fix x_prime[10];
fix xp_top, xp_bot;
fix x_top, x_bot;
fix y_top, y_bot;
fix dy_top, dy_bot;
int xp_min, xp_max, xp_next;
int y_min, y_max, yr_min, yr_max, yl_min, yl_max;
int n_min, n_top, n_bot;
int j;
pi.scale = grd_bm.w;
pi.scan_slope = ps->scan_slope;
pi.dp = ps->dp;
pi.clut = ps->clut;
if (fix_abs(pi.scan_slope) >= FIX_UNIT)
return;
if (bm->row != 1 << (bm->wlog))
return;
if (bm->h != 1 << (bm->hlog))
return;
pi.u_mask = bm->row - 1;
pi.v_mask = (bm->h - 1) << bm->wlog;
pi.v_shift = 16 - bm->wlog;
xp_min = xp_max = fix_cint(x_prime[n_min = 0] = vpl[0]->x - fix_mul(vpl[0]->y, ps->scan_slope));
for (j = 1; j < n; j++) {
pi.xp = fix_cint(x_prime[j] = vpl[j]->x - fix_mul(vpl[j]->y, ps->scan_slope));
if (pi.xp < xp_min) {
xp_min = pi.xp;
n_min = j;
}
if (pi.xp > xp_max)
xp_max = pi.xp;
}
if (xp_max == xp_min)
return;
pi.denom = fix_16_20(ps->c + fix_mul(ps->a, x_prime[0]));
pi.u0 =
vpl[0]->u - fix_div(fix_mul(vpl[0]->x, ps->alpha_u) + fix_mul(vpl[0]->y, ps->beta_u) + ps->gamma_u, pi.denom);
pi.v0 =
vpl[0]->v - fix_div(fix_mul(vpl[0]->x, ps->alpha_v) + fix_mul(vpl[0]->y, ps->beta_v) + ps->gamma_v, pi.denom);
n_top = n_bot = n_min;
pi.xp = xp_min;
while (fix_cint(x_prime[(n_top + 1) % n]) == pi.xp)
n_top = (n_top + 1) % n;
while (fix_cint(x_prime[(n_bot + n - 1) % n]) == pi.xp)
n_bot = (n_bot + n - 1) % n;
pi.xp--;
pi.denom = fix_16_20(ps->c + pi.xp * ps->a);
pi.unum = ps->gamma_u + ps->alpha_u * pi.xp;
pi.dunum = ps->beta_u + fix_mul(ps->scan_slope, ps->alpha_u);
pi.vnum = ps->gamma_v + ps->alpha_v * pi.xp;
pi.dvnum = ps->beta_v + fix_mul(ps->scan_slope, ps->alpha_v);
if (n_bot != n_top) {
pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
pi.y = fix_cint(vpl[n_top]->y);
pi.yl = fix_cint(vpl[n_bot]->y);
if (pi.scan_slope > 0) {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
} else {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
}
if (pi.y < y_min)
pi.y = y_min;
if (pi.yl > y_max)
pi.yl = y_max;
pi.yr0 = pi.yr = pi.yl;
pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp - 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dxl - pi.dyl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
xp_min--; /* first line already done */
}
pi.xp++;
while (pi.xp < xp_max) {
/* check top edge */
if (fix_cint(x_prime[n_top]) <= pi.xp) {
int n_prev;
fix d;
do {
if (fix_cint(x_prime[n_top]) == pi.xp)
n_prev = n_top;
if (++n_top == n)
n_top = 0;
} while (fix_cint(x_prime[n_top]) <= pi.xp);
xp_top = x_prime[n_prev];
x_top = vpl[n_prev]->x;
y_top = vpl[n_prev]->y;
yl_min = fix_cint(y_top);
yl_max = fix_cint(vpl[n_top]->y);
pi.dxl = (vpl[n_top]->x - x_top) / pi.scale;
pi.dyl = (vpl[n_top]->y - y_top) / pi.scale;
pi.cl = -fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, x_top);
d = pi.dxl - fix_mul(pi.dyl, pi.scan_slope);
dy_top = fix_div(pi.dyl, d);
y_top = fix_div(fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, fix_ceil(xp_top) - x_top), d);
if (yl_max < yl_min) {
fix foo = yl_min;
yl_min = yl_max;
yl_max = foo;
}
if (fix_mul(vpl[n_top]->y - FIX_UNIT, pi.dxl) - fix_mul(vpl[n_top]->x - pi.scan_slope, pi.dyl) + pi.cl <
0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dxl - pi.dyl;
else
pi.dtl = pi.dyl + pi.dxl;
xp_top = x_prime[n_top];
}
/* check bot edge */
if (fix_cint(x_prime[n_bot]) <= pi.xp) {
int n_prev;
fix d;
do {
if (fix_cint(x_prime[n_bot]) == pi.xp)
n_prev = n_bot;
if (--n_bot < 0)
n_bot = n - 1;
} while (fix_cint(x_prime[n_bot]) <= pi.xp);
xp_bot = x_prime[n_prev];
x_bot = vpl[n_prev]->x;
y_bot = vpl[n_prev]->y;
yr_min = fix_cint(y_bot);
yr_max = fix_cint(vpl[n_bot]->y);
pi.dxr = (vpl[n_bot]->x - x_bot) / pi.scale;
pi.dyr = (vpl[n_bot]->y - y_bot) / pi.scale;
pi.cr = -fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, x_bot);
d = pi.dxr - fix_mul(pi.dyr, pi.scan_slope);
dy_bot = fix_div(pi.dyr, d);
y_bot = fix_div(fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, fix_ceil(xp_bot) - x_bot), d);
if (yr_max < yr_min) {
fix foo = yr_min;
yr_min = yr_max;
yr_max = foo;
}
if (fix_mul(vpl[n_bot]->y - FIX_UNIT, pi.dxr) - fix_mul(vpl[n_bot]->x - pi.scan_slope, pi.dyr) + pi.cr <
0) {
pi.dyr = -pi.dyr;
pi.dxr = -pi.dxr;
pi.cr = -pi.cr;
}
if (pi.scan_slope > 0)
pi.dtr = pi.dxr - pi.dyr;
else
pi.dtr = pi.dyr + pi.dxr;
xp_bot = x_prime[n_bot];
}
xp_next = (xp_bot < xp_top) ? fix_cint(xp_bot) : fix_cint(xp_top);
/* do 0th scanline if at xp_min */
if (pi.xp == xp_min) {
y_top -= dy_top;
y_bot -= dy_bot;
pi.xp--;
}
for (; pi.xp < xp_next; pi.xp++) {
if ((pi.xp + 1 == xp_max) && (n_top != n_bot)) {
pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
pi.y = fix_cint(vpl[n_top]->y);
pi.yl = fix_cint(vpl[n_bot]->y);
if (pi.scan_slope > 0) {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
} else {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
}
if (pi.y < y_min)
pi.y = y_min;
if (pi.yl > y_max)
pi.yl = y_max;
pi.yr0 = pi.yr = pi.yl;
pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp + 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
pi.dyl = -pi.dyl;
pi.dxl = -pi.dxl;
pi.cl = -pi.cl;
}
if (pi.scan_slope > 0)
pi.dtl = pi.dxl - pi.dyl;
else
pi.dtl = pi.dyl + pi.dxl;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
pi.xp = xp_max;
break;
}
if (dy_top > 0) {
pi.y = fix_fint(y_top);
pi.yl = fix_cint(y_top + dy_top);
} else {
pi.y = fix_fint(y_top + dy_top);
pi.yl = fix_cint(y_top);
}
if (dy_bot > 0) {
pi.yr0 = fix_fint(y_bot);
pi.yr = fix_cint(y_bot + dy_bot);
} else {
pi.yr0 = fix_fint(y_bot + dy_bot);
pi.yr = fix_cint(y_bot);
}
if (pi.scan_slope > 0) {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
} else {
y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
}
if (yl_min > y_min)
y_min = yl_min;
if (yr_max < y_max)
y_max = yr_max;
if (pi.yr > y_max)
pi.yr = y_max;
if (pi.yr0 > y_max)
pi.yr0 = y_max;
if (pi.yl > pi.yr0)
pi.yl = pi.yr0;
if (pi.y < y_min)
pi.y = y_min;
((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
y_top += dy_top, y_bot += dy_bot;
pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
}
}
}
@@ -0,0 +1,95 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8p.h $
* $Revision: 1.11 $
* $Author: kevin $
* $Date: 1994/11/02 19:39:49 $
*
* Miscellaneous stuff needed by the flat8 perspective mappers.
* Includes 3 and 12 bit integer fixed point macros.
*
* This file is part of the 2d library.
*
* $Log: fl8p.h $
* Revision 1.11 1994/11/02 19:39:49 kevin
* Use 20 bit integer fixed point for bitmap coord intermediates to avoid
* overflows in svga.
*
* Revision 1.10 1994/07/18 17:04:27 kevin
* removed unnecessary includes.
*
* Revision 1.9 1994/01/16 12:04:44 kevin
* Added clut lighting tolerance global declaration.
*
* Revision 1.8 1994/01/03 22:26:11 kevin
* Added declaration for global grd_per_setup.
*
* Revision 1.7 1993/12/17 01:00:57 kevin
* Added egregious error constants.
*
* Revision 1.6 1993/12/15 02:49:06 kevin
* Added wlog and hlog to context.
*
* Revision 1.5 1993/12/14 22:31:14 kevin
* Moved declaration of grd_per_context to
* grpm.h so everyone can use it.
*
* Revision 1.4 1993/12/08 23:44:52 kevin
* Added vtab to per_setup structure for non/power/of/2 support.
*
* Revision 1.3 1993/12/04 17:28:28 kevin
* Added clut field to per_setup structure.
*
* Revision 1.2 1993/12/04 12:33:01 kevin
* Added new structures, new fixed point primitives.
*
* Revision 1.1 1993/11/18 23:42:36 kevin
* Initial revision
*
*/
#ifndef __FL8P_H
#define __FL8P_H
#define ACENT (grd_bm.w >> 1)
#define BCENT (grd_bm.h >> 1)
#define SCALE 0x200
#define GR_PER_CODE_OK 0
#define GR_PER_CODE_MEMERR 1
#define GR_PER_CODE_BADPLANE 2
#define GR_PER_CODE_BADDENOM 3
#define GR_PER_CODE_BADINDEX 4
#define GR_PER_CODE_LIN 5
#define GR_PER_CODE_WALL 6
#define GR_PER_CODE_FLOOR 7
#define GR_PER_CODE_BIGSLOPE 8
#define GR_PER_CODE_SMALLSLOPE 9
#define HS_TS_ERR 10
#define HS_TB_ERR 11
#define VS_TS_ERR 12
#define VS_TB_ERR 13
extern ubyte flat8_per_ltol;
extern ubyte flat8_per_wftol;
extern fix gr_clut_lit_tol;
#endif
@@ -0,0 +1,59 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8p24.c $
* $Revision: 1.5 $
* $Author: kevin $
* $Date: 1994/10/17 14:59:59 $
*
* Routines for drawing 24-bit pixels onto a flat 8 canvas.
*
* This file is part of the 2d library.
*/
#include "clpcon.h"
#include "cnvdat.h"
#include "rgb.h"
#include "scrdat.h"
/* set an unclipped pixel in bank-switched memory. draws 8-8-8 long
rgb c at (x,y). */
void flat8_set_upixel24(long c, short x, short y) {
uchar *p;
int i;
i = gr_index_lrgb(c);
p = grd_bm.bits + grd_bm.row * y + x;
*p = grd_ipal[i];
}
/* set a clipped pixel in bank-switched memory. draws an 8-8-8 long
rgb c at (x,y). return the clip code. */
int flat8_set_pixel24(long c, short x, short y) {
uchar *p;
int i;
if (x < grd_clip.left || x > grd_clip.right || y < grd_clip.top || y > grd_clip.bot)
return CLIP_ALL;
i = gr_index_lrgb(c);
p = grd_canvas->bm.bits + grd_canvas->bm.row * y + x;
*p = grd_ipal[i];
return CLIP_NONE;
}
@@ -0,0 +1,86 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8pix.c $
* $Revision: 1.5 $
* $Author: kevin $
* $Date: 1994/08/16 13:14:01 $
*
* Routines for drawing pixels into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8pix.c $
* Revision 1.5 1994/08/16 13:14:01 kevin
* Added pixel primitives for all fill modes.
*
* Revision 1.4 1993/10/19 09:50:49 kaboom
* Replaced #include "grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/01 16:00:45 kaboom
* Converted to include clpcon.h instead of clip.h
*
* Revision 1.2 1993/05/16 00:33:22 kaboom
* Fixed clipped case to handle new padded clipping rectangle.
*
* Revision 1.1 1993/02/16 14:16:16 kaboom
* Initial revision
*/
#include "blend.h"
#include "cnvdat.h"
#include "fl8tf.h"
/* draws an unclipped pixel of the given color at (x, y) on the canvas. */
void flat8_set_upixel(long color, short x, short y) {
uchar *p;
p = grd_bm.bits + grd_bm.row * y + x;
*p = color;
}
void flat8_clut_set_upixel(long color, short x, short y) {
uchar *p;
p = grd_bm.bits + grd_bm.row * y + x;
*p = ((uchar *)grd_gc.fill_parm)[color];
}
void flat8_xor_set_upixel(long color, short x, short y) {
uchar *p;
p = grd_bm.bits + grd_bm.row * y + x;
*p = color ^ *p;
}
void flat8_blend_set_upixel(long color, short x, short y) {
uchar *p;
p = grd_bm.bits + grd_bm.row * y + x;
*p = gr_blend(color, *p, grd_gc.fill_parm);
}
// MLA #pragma off (unreferenced)
void flat8_solid_set_upixel(long color, short x, short y) {
uchar *p;
p = grd_bm.bits + grd_bm.row * y + x;
*p = (uchar)grd_gc.fill_parm;
}
// MLA #pragma on (unreferenced)
@@ -0,0 +1,144 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8ply.c $
* $Revision: 1.1 $
* $Author: kevin $
* $Date: 1994/08/16 13:11:09 $
*
* Routines for drawing flat shaded polygons onto a flat 8 canvas.
*
* This file is part of the 2d library.
*/
#include "cnvdat.h"
#include "gente.h"
#include "lg.h"
#include "poly.h"
#include "tlucdat.h"
#include "tmapint.h"
#include <stdint.h>
#include <string.h>
// prototypes
int gri_poly_loop(grs_tmap_loop_info *ti);
void gri_solid_poly_init(grs_tmap_loop_info *ti);
void gri_poly_init(grs_tmap_loop_info *ti);
void gri_clut_poly_init(grs_tmap_loop_info *ti);
void gri_tpoly_init(grs_tmap_loop_info *ti);
void gri_clut_tpoly_init(grs_tmap_loop_info *ti);
int gri_poly_loop(grs_tmap_loop_info *ti) {
int d;
uchar c = (uchar)(intptr_t)(ti->bm.bits); /* actually, fill_parm */
uchar *bm_bits = ti->bm.bits;
uchar *ti_d = ti->d;
fix ti_left_x = ti->left.x;
fix ti_right_x = ti->right.x;
uchar *ti_clut = ti->clut;
uchar ti_hlog = ti->bm.hlog;
ushort grow = grd_bm.row;
fix ti_left_dx = ti->left.dx;
fix ti_right_dx = ti->right.dx;
do {
if ((d = fix_cint(ti_right_x) - fix_cint(ti_left_x)) > 0) {
int x;
switch (ti_hlog) {
case GRL_OPAQUE:
LG_memset(ti_d + fix_cint(ti_left_x), c, d);
break;
case GRL_TLUC8:
for (x = fix_cint(ti_left_x); x < fix_cint(ti_right_x); x++)
ti_d[x] = bm_bits[ti_d[x]];
break;
case GRL_CLUT | GRL_TLUC8:
for (x = fix_cint(ti_left_x); x < fix_cint(ti_right_x); x++)
ti_d[x] = ti_clut[bm_bits[ti_d[x]]];
break;
}
} else if (d < 0) {
return TRUE;
}
/* update span extrema and destination. */
ti_d += grow;
ti_left_x += ti_left_dx;
ti_right_x += ti_right_dx;
} while ((--(ti->n)) > 0);
ti->d = ti_d;
ti->right.x = ti_right_x;
ti->left.x = ti_left_x;
return FALSE;
}
void gri_solid_poly_init(grs_tmap_loop_info *ti) {
ti->bm.bits = ti->clut; /* set fill_parm */
ti->bm.hlog = GRL_OPAQUE;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_poly_loop;
ti->top_edge_func = (void (*)())gri_x_edge;
ti->bot_edge_func = (void (*)())gri_x_edge;
}
void gri_poly_init(grs_tmap_loop_info *ti) {
ti->bm.hlog = GRL_OPAQUE;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_poly_loop;
ti->top_edge_func = (void (*)())gri_x_edge;
ti->bot_edge_func = (void (*)())gri_x_edge;
}
void gri_clut_poly_init(grs_tmap_loop_info *ti) {
ti->bm.bits = (uchar *)(intptr_t)ti->clut[(intptr_t)ti->bm.bits];
ti->bm.hlog = GRL_OPAQUE;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_poly_loop;
ti->top_edge_func = (void (*)())gri_x_edge;
ti->bot_edge_func = (void (*)())gri_x_edge;
}
void gri_tpoly_init(grs_tmap_loop_info *ti) {
if (tluc8tab[(intptr_t)(ti->bm.bits)] != NULL) {
ti->bm.bits = tluc8tab[(intptr_t)ti->bm.bits];
ti->bm.hlog = GRL_TLUC8;
} else {
ti->bm.hlog = GRL_OPAQUE;
}
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_poly_loop;
ti->top_edge_func = (void (*)())gri_x_edge;
ti->bot_edge_func = (void (*)())gri_x_edge;
}
void gri_clut_tpoly_init(grs_tmap_loop_info *ti) {
// DebugString("gri_clut_tpoly_init");
if (tluc8tab[(intptr_t)(ti->bm.bits)] != NULL) {
ti->bm.bits = tluc8tab[(intptr_t)ti->bm.bits];
ti->bm.hlog = GRL_TLUC8 | GRL_CLUT;
} else {
ti->bm.bits = (uchar *)(intptr_t)ti->clut[(intptr_t)ti->bm.bits];
ti->bm.hlog = GRL_OPAQUE;
}
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_poly_loop;
ti->top_edge_func = (void (*)())gri_x_edge;
ti->bot_edge_func = (void (*)())gri_x_edge;
}
@@ -0,0 +1,62 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8pnt.c $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:51 $
*
* Routines for drawing points into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8pnt.c $
* Revision 1.4 1993/10/19 09:50:51 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/01 16:00:46 kaboom
* Converted to include clpcon.h instead of clip.h
*
* Revision 1.2 1993/05/16 00:33:03 kaboom
* Fixed clipped case to handle new padded clipping rectangle.
*
* Revision 1.1 1993/02/16 14:16:27 kaboom
* Initial revision
*/
#include "clpcon.h"
#include "cnvdat.h"
void flat8_upoint(short x, short y) {
uchar *p;
p = grd_bm.bits + y * grd_bm.row + x;
*p = grd_gc.fcolor;
}
int flat8_point(short x, short y) {
uchar *p;
if (x < grd_clip.left || x >= grd_clip.right || y < grd_clip.top || y >= grd_clip.bot)
return CLIP_ALL;
p = grd_bm.bits + grd_bm.row * y + x;
*p = grd_gc.fcolor;
return CLIP_NONE;
}
@@ -0,0 +1,61 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8rect.c $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 09:50:53 $
*
* Routines for drawing rectangles into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8rect.c $
* Revision 1.4 1993/10/19 09:50:53 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/08 01:15:29 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.2 1993/05/04 18:43:51 kaboom
* Changed rectangle to omit the right and bottom edges.
*
* Revision 1.1 1993/02/16 14:17:05 kaboom
* Initial revision
*/
#include "cnvdat.h"
#include "lg.h"
#include <string.h>
void flat8_urect(short left, short top, short right, short bot) {
uchar *p;
int w, h;
int grow = grd_bm.row;
long fcolor = grd_gc.fcolor;
p = grd_bm.bits + top * grow + left;
w = right - left;
h = bot - top;
while (h-- > 0) {
LG_memset(p, fcolor, w);
p += grow;
}
}
@@ -0,0 +1,35 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8row.c $
* $Revision: 1.1 $
* $Author: kaboom $
* $Date: 1993/04/29 18:46:46 $
*
* Row bytes calculator for flat 8 bitmaps.
*
* This file is part of the 2d library.
*
* $Log: fl8row.c $
* Revision 1.1 1993/04/29 18:46:46 kaboom
* Initial revision
*
*/
short flat8_calc_row(short w) { return w; }
@@ -0,0 +1,264 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8rsd8.c $
* $Revision: 1.6 $
* $Author: kevin $
* $Date: 1994/10/27 18:26:56 $
*
* Routines for drawing rsd bitmaps into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8rsd8.c $
* Revision 1.6 1994/10/27 18:26:56 kevin
* fixed gr_rsd8_blit prototype.
*
* Revision 1.5 1994/10/25 15:13:14 kevin
* Renamed funcs, use fast rsd blitter when possible.
*
* Revision 1.4 1993/10/19 09:50:54 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.3 1993/10/01 16:00:47 kaboom
* Converted to include clpcon.h instead of clip.h
*
* Revision 1.2 1993/07/13 17:47:13 kaboom
* Fixed bugs in clipping case off right edge. Updated for padded clipping
* rectangle.
*
* Revision 1.1 1993/02/16 14:17:21 kaboom
* Initial revision
*
********************************************************************
* Log from old flat8.c:
* Revision 1.7 1992/12/14 18:08:40 kaboom
* Fixed bug in flat8_rsd8_[u]bitmap() -- were omitting bottom lines.
*/
#include "clpcon.h"
#include "cnvdat.h"
#include "fl8tf.h"
#include "general.h"
#include "grdbm.h"
#include "lg.h"
#include "rsd.h"
#include <string.h>
// prototypes
void gr_rsd8_blit(uchar *rsd_src, uchar *dst, int grd_bm_row, int bm_w);
//### MLA- not supposed to be used (PC code is in RSDBLT.ASM)
void gr_rsd8_blit(uchar *rsd_src, uchar *dst, int grd_bm_row, int bm_w) {
DEBUG("%s: ask mark", __FUNCTION__);
}
void gri_flat8_rsd8_ubitmap(grs_bitmap *bm, short x, short y) {
/* uchar *p_dst;
uchar *rsd_src; // rsd source buffer
rsd_src = bm->bits;
p_dst = grd_bm.bits + grd_bm.row*y + x;
gr_rsd8_blit(rsd_src,p_dst,grd_bm.row,bm->w);*/
unpack_rsd8_ubitmap(bm, x, y);
}
int gri_flat8_rsd8_bitmap(grs_bitmap *bm, short x_left, short y_top) {
short x, y; /* current destination position */
short x_right, y_bot; /* opposite edges of bitmap */
short x_off, y_off; /* x,y offset for clip */
ulong start_byte; /* byte to start drawing */
ulong cur_byte; /* current position within rsd */
uchar *p_dst;
uchar *rsd_src; /* rsd source buffer */
short rsd_code; /* last rsd opcode */
short rsd_count; /* count for last opcode */
short op_count; /* operational count */
int code; /* clip code to return */
rsd_src = bm->bits;
x = x_left;
y = y_top;
x_off = y_off = cur_byte = rsd_count = 0;
x_right = x_left + bm->w;
y_bot = y_top + bm->h;
/* clip bitmap to rectangular clipping window. */
if (x_left > grd_clip.right || x_right <= grd_clip.left || y_top > grd_clip.bot || y_bot <= grd_clip.top)
/* completely clipped, forget it. */
return CLIP_ALL;
code = CLIP_NONE;
if (x_left < grd_clip.left) {
/* clipped off left edge. */
x_off = grd_clip.left - x_left;
x = grd_clip.left;
code |= CLIP_LEFT;
}
if (y < grd_clip.top) {
/* clipped off top edge. */
y_off = grd_clip.top - y_top;
y = grd_clip.top;
code |= CLIP_TOP;
}
if (x_right >= grd_clip.right) {
/* clipped off right edge. */
x_right = grd_clip.right;
code |= CLIP_RIGHT;
}
if (y_bot > grd_clip.bot) {
/* clipped off bottom edge. */
y_bot = grd_clip.bot;
code |= CLIP_BOT;
}
if (code == CLIP_NONE) {
gr_ubitmap(bm, x_left, y_top);
return CLIP_NONE;
}
if (y_off > 0 || x_off > 0) {
/* been clipped of left and/or top, so we need to skip from beginning
of rsd buffer to be at x_off,y_off within rsd bitmap. */
start_byte = y_off * bm->row + x_off;
while (cur_byte < start_byte) {
if (rsd_count == 0)
/* no pending opcodes, get a new one. */
RSD_GET_TOKEN();
if (cur_byte + rsd_count <= start_byte) {
/* current code doesn't hit start_byte yet, so skip all of it. */
switch (rsd_code) {
case RSD_RUN:
/* advance past 1 byte of run color. */
rsd_src++;
break;
case RSD_SKIP:
break;
default: /* RSD_DUMP */
/* advance past rsd_count bytes of dump pixel data. */
rsd_src += rsd_count;
break;
}
cur_byte += rsd_count;
rsd_count = 0;
} else {
/* current code goes past start_byte, so skip only enough to get
to start_byte. */
op_count = start_byte - cur_byte;
switch (rsd_code) {
case RSD_RUN:
break;
case RSD_SKIP:
break;
default: /* RSD_DUMP */
rsd_src += op_count;
break;
}
cur_byte += op_count;
rsd_count -= op_count;
}
}
}
p_dst = grd_bm.bits + y * grd_bm.row + x;
/* process each scanline in two chunks. the first is the clipped section
from the right edge, wrapping around to to the left. the second is the
unclipped area in the middle. */
while (y < y_bot) {
/* clipped section. */
while (x < x_left + x_off) {
if (rsd_count == 0)
RSD_GET_TOKEN();
if (x + rsd_count <= x_left + x_off) {
switch (rsd_code) {
case RSD_RUN:
rsd_src++;
break;
case RSD_SKIP:
break;
default: /* RSD_DUMP */
rsd_src += rsd_count;
break;
}
x += rsd_count;
rsd_count = 0;
} else {
op_count = x_left + x_off - x;
switch (rsd_code) {
case RSD_RUN:
break;
case RSD_SKIP:
break;
default: /* RSD_DUMP */
rsd_src += op_count;
break;
}
rsd_count -= op_count;
x += op_count;
}
}
/* section to draw. */
while (x < x_right) {
if (rsd_count == 0)
RSD_GET_TOKEN();
if (x + rsd_count <= x_right) {
switch (rsd_code) {
case RSD_RUN:
LG_memset(p_dst, *rsd_src, rsd_count);
rsd_src++;
break;
case RSD_SKIP:
break;
default: /* RSD_DUMP */
LG_memcpy(p_dst, rsd_src, rsd_count);
rsd_src += rsd_count;
break;
}
x += rsd_count;
p_dst += rsd_count;
rsd_count = 0;
} else {
op_count = x_right - x;
switch (rsd_code) {
case RSD_RUN:
LG_memset(p_dst, *rsd_src, op_count);
break;
case RSD_SKIP:
break;
default: /* RSD_DUMP */
LG_memcpy(p_dst, rsd_src, op_count);
rsd_src += op_count;
break;
}
x += op_count;
p_dst += op_count;
rsd_count -= op_count;
}
}
/* reset x to be beginning of line and set y to next scanline. */
x -= bm->w;
p_dst += grd_bm.row - (x_right - x_left) + x_off;
y++;
}
rsd_done:
return code;
}
+197
View File
@@ -0,0 +1,197 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
//
// $Source: r:/prj/lib/src/2d/RCS/fl8s.asm $
// $Revision: 1.1 $
// $Author: kevin $
// $Date: 1994/08/16 12:34:32 $
//
// Inner loops of scaling and clut scaling primitives.
//
// This file is part of the 2d library.
//
#include "cnvdat.h"
#include "gente.h"
#include "grnull.h"
#include "poly.h"
#include "tmapint.h"
// globals
long ADD_DEST_OFF;
long ADD_DV_FRAC_OFF;
long AND_BM_ROW_OFF;
long ADD_SRC_OFF;
long SET_REPS_OFF;
long SET_OFFSET_OFF;
long JMP_LOOP_MIDDLE_OFF;
#define unroll_num 4
#define unroll_log 2
// externs
extern int gri_poly_loop(grs_tmap_loop_info *ti);
// internal prototypes
int gri_scale_umap_loop_PPC(grs_tmap_loop_info *tli);
int gri_scale_umap_loop_68K(grs_tmap_loop_info *tli);
// This file contains the scalers for both 68K and PowerPC
// First the routines that are generic to both, then the PowerPC routines, then
// 68K
// ------------------------------------------------------------------------
// Generic (68K & PowerPC) routines
// ------------------------------------------------------------------------
// ========================================================================
// opaque solid polygon scaler
int gri_opaque_solid_scale_umap_init(grs_tmap_loop_info *info, grs_vertex **vert) {
info->left_edge_func = (void (*)())gri_scale_edge;
info->right_edge_func = (void (*)())gr_null;
info->bm.hlog = 0;
info->bm.bits = info->clut;
info->loop_func = (void (*)())gri_poly_loop;
info->d = ((uchar *)((long)grd_canvas->bm.row * (long)info->y));
info->d += (long)grd_canvas->bm.bits;
return (0);
}
// ------------------------------------------------------------------------
// PowerPC routines
// ------------------------------------------------------------------------
// ========================================================================
// transparent solid polygon scaler
int gri_trans_solid_scale_umap_init(grs_tmap_loop_info *tli, grs_vertex **vert) {
tli->bm.hlog = GRL_TRANS | GRL_SOLID;
tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
return (0);
}
// ========================================================================
// transparent bitmap scaler
int gri_trans_scale_umap_init(grs_tmap_loop_info *tli, grs_vertex **vert) {
tli->bm.hlog = GRL_TRANS;
tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
return (0);
}
// ========================================================================
// opaque bitmap scaler
int gri_opaque_scale_umap_init(grs_tmap_loop_info *tli) {
tli->bm.hlog = GRL_OPAQUE;
tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
return (0);
}
// ========================================================================
// transparent clut bitmap scaler
int gri_trans_clut_scale_umap_init(grs_tmap_loop_info *tli) {
tli->bm.hlog = GRL_TRANS | GRL_CLUT;
tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
return (0);
}
// ========================================================================
// opaque clut bitmap scaler
int gri_opaque_clut_scale_umap_init(grs_tmap_loop_info *tli) {
tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
tli->right_edge_func = gr_null;
tli->left_edge_func = (void (*)())gri_scale_edge;
return (0);
}
// ========================================================================
// main inside loop for PPC scalers
int gri_scale_umap_loop_PPC(grs_tmap_loop_info *tli) {
fix u, ul, du;
int x;
uchar k;
fix xl, xr, dx, d;
uchar *p_src, *p_dest;
xl = fix_cint(tli->left.x);
xr = fix_cint(tli->right.x);
if (xr <= xl)
return TRUE;
ul = tli->left.u;
dx = tli->right.x - tli->left.x;
du = fix_div(tli->right.u - ul, dx);
d = fix_ceil(tli->left.x) - tli->left.x;
ul += fix_mul(du, d);
do {
p_src = tli->bm.bits + tli->bm.row * fix_int(tli->left.v);
p_dest = grd_bm.bits + (grd_bm.row * tli->y) + xl;
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (x = xl, u = ul; x < xr; x++) {
*(p_dest++) = p_src[fix_fint(u)]; // gr_fill_upixel(k,x,tli->y);
u += du;
}
break;
case GRL_TRANS:
for (x = xl, u = ul; x < xr; x++) {
k = p_src[fix_fint(u)];
if (k != 0)
*p_dest = k; // gr_fill_upixel(k,x,tli->y);
u += du;
p_dest++;
}
break;
case GRL_OPAQUE | GRL_CLUT:
for (x = xl, u = ul; x < xr; x++) {
*(p_dest++) = tli->clut[p_src[fix_fint(u)]]; // gr_fill_upixel(tli->clut[k],x,tli->y);
u += du;
}
break;
case GRL_TRANS | GRL_CLUT:
for (x = xl, u = ul; x < xr; x++) {
k = p_src[fix_fint(u)];
if (k != 0)
*p_dest = tli->clut[k]; // gr_fill_upixel(tli->clut[k],x,tli->y);
u += du;
p_dest++;
}
break;
case GRL_TRANS | GRL_SOLID:
for (x = xl, u = ul; x < xr; x++) {
k = p_src[fix_fint(u)];
if (k != 0)
*p_dest = tli->solid; // gr_fill_upixel((uchar )(tli->clut),x,tli->y);
u += du;
p_dest++;
}
break;
}
tli->left.v += tli->left.dv;
tli->y++;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
@@ -0,0 +1,95 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8slin.c $
* $Revision: 1.5 $
* $Author: lmfeeney $
* $Date: 1994/06/11 01:24:10 $
*
* Routine to draw a gouraud shaded line to a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8slin.c $
* Revision 1.5 1994/06/11 01:24:10 lmfeeney
* guts of the routine moved to fl8{c,s}lin.h, per fill type
* line drawers are created by defining macros and including
* this file
*
* Revision 1.4 1994/05/06 18:19:13 lmfeeney
* rewritten for greater accuracy and speed
*
* Revision 1.3 1993/10/19 09:50:58 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.2 1993/10/01 16:01:20 kaboom
* Pared down includes to reduce dependencies.
*
* Revision 1.1 1993/07/01 22:12:15 spaz
* Initial revision
*/
#include "cnvdat.h"
#include "plytyp.h"
#include <stdlib.h>
/* not all fill routines use all parms */
// MLA #pragma off (unreferenced)
#undef macro_plot_i
#define macro_plot_i(x, p, i) \
do { \
p[x] = i; \
} while (0)
void gri_flat8_usline_norm(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8slin.h"
}
#undef macro_plot_i
#define macro_plot_i(x, p, i) \
do { \
p[x] = (long)(((uchar *)parm)[i]); \
} while (0)
void gri_flat8_usline_clut(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8slin.h"
}
#undef macro_plot_i
#define macro_plot_i(x, p, i) \
do { \
p[x] = p[x] ^ i; \
} while (0)
void gri_flat8_usline_xor(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8slin.h"
}
/* punt */
#undef macro_plot_i
#define macro_plot_i(x, p, i) \
do { \
p[x] = i; \
} while (0)
void gri_flat8_usline_blend(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8slin.h"
}
@@ -0,0 +1,265 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8slin.h $
* $Revision: 1.1 $
* $Author: lmfeeney $
* $Date: 1994/06/11 00:50:38 $
*
* Routine to draw a gouraud shaded line to a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8slin.h $
* Revision 1.1 1994/06/11 00:50:38 lmfeeney
* Initial revision
*
* Revision 1.4 1994/05/06 18:19:13 lmfeeney
* rewritten for greater accuracy and speed
*
* Revision 1.3 1993/10/19 09:50:58 kaboom
* Replaced #include <grd.h> with new headers split from grd.h.
*
* Revision 1.2 1993/10/01 16:01:20 kaboom
* Pared down includes to reduce dependencies.
*
* Revision 1.1 1993/07/01 22:12:15 spaz
* Initial revision
*/
/* Draw a goroud-shaded line, specified by indices into the palette.
be warned, weird precision bugs abound (check out test programs
in /project/lib/src/2d/test).
These have been mostly corrected. See also note.txt for correctness
arguement of new algorithm
*/
/* NB: directionality policy -- reversible
Lines are drawn in order of increasing x or increasing y,
for lines that have greater x or y extent, repsectively.
This is done for all lines, including horiz., vert., and
45' lines (increasing x).
*/
/* NB: endpoint policy -- inclusive The left and top endpoints are
'trunc'-ed. The right and bottom endpoints exclude the ceiling,
or equivlalently, include the pixel containing the line. This is
calculated by subtracting epsilon (i.e. 1/65536) from its
fixed-point representation, then trunc'ing.
This makes sense if you note that open interval right
< ceil (x)
is the same as
<= trunc (x - e)
*/
fix x0, y0, x1, y1;
fix dx, dy; /* deltas in x and y */
fix t; /* temporary fix */
fix i0, i1;
fix di; /* delta intensity */
uchar *p; /* pointer into the canvas */
x0 = v0->x;
y0 = v0->y;
x1 = v1->x;
y1 = v1->y;
i0 = (fix)v0->i;
i1 = (fix)v1->i;
/* set endpoints
note that this cannot go negative or change octant, since the ==
case is excluded */
if (x0 < x1) {
x1 -= 1; /* e.g. - epsilon */
} else if (x0 > x1) {
x0 -= 1;
}
if (y0 < y1) {
y1 -= 1;
} else if (y0 > y1) {
y0 -= 1;
}
dx = fix_trunc(x1) - fix_trunc(x0); /* x extent in pixels, (macro is flakey) */
dx = fix_abs(dx);
dy = fix_trunc(y1) - fix_trunc(y0); /* y extent in pixels */
dy = fix_abs(dy);
if (dx == 0 && dy == 0)
return;
/* three cases: absolute value dx < = > dy
along the longer dimension, the fixpoint x0 (or y0) is treated
as an int
the points are swapped if needed and the rgb initial and deltas
are calculated accordingly
there are two or three sub-cases - a horizontal or vertical line,
and the dx or dy being added or subtracted. dx and dy
are kept as absolute values and +/- is managed in the
two separate inner loops if it's a dy, since you also have to
manage the canvas pointer
if y is being changed by 'dy' and x is being incremented, do a
FunkyBitCheck (TM) to see whether the integer part of y has changed
and if it has, resetting the the canvas pointer to the next row
if x is being changed by 'dx' and y is being incremented, just
add or subtract row to increment y in the canvas
the endpoints are walked inclusively in all cases, see above
45' degree lines are explicitly special cased -- because it
all runs as integers, but it's probably not frequent enough
to justify the check
*/
if (dx > dy) {
x0 = fix_int(x0);
x1 = fix_int(x1);
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
t = i0;
i0 = i1;
i1 = t;
}
p = grd_bm.bits + grd_bm.row * (fix_int(y0));
di = fix_div((i1 - i0), dx);
if ((fix_int(y0)) == (fix_int(y1))) {
while (x0 <= x1) {
macro_plot_i(x0, p, fix_fint(i0));
x0++;
i0 += di;
}
} else if (y0 < y1) {
dy = fix_div((y1 - y0), dx);
while (x0 <= x1) {
macro_plot_i(x0, p, fix_fint(i0));
x0++;
y0 += dy;
p += (grd_bm.row & (-(fix_frac(y0) < dy)));
i0 += di;
}
} else {
dy = fix_div((y0 - y1), dx);
while (x0 <= x1) {
macro_plot_i(x0, p, fix_fint(i0));
x0++;
p -= (grd_bm.row & (-(fix_frac(y0) < dy)));
y0 -= dy;
i0 += di;
}
}
} else if (dy > dx) {
y0 = fix_int(y0);
y1 = fix_int(y1);
if (y0 > y1) {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
t = i0;
i0 = i1;
i1 = t;
}
p = grd_bm.bits + grd_bm.row * y0;
di = fix_div((i1 - i0), dy);
if ((fix_int(x0)) == (fix_int(x1))) {
x0 = fix_int(x0);
while (y0 <= y1) {
macro_plot_i(x0, p, fix_fint(i0));
y0++;
p += grd_bm.row;
i0 += di;
}
} else {
dx = fix_div((x1 - x0), dy);
while (y0 <= y1) {
macro_plot_i(fix_fint(x0), p, fix_fint(i0));
x0 += dx;
y0++;
p += grd_bm.row;
i0 += di;
}
}
} else { /* dy == dx, walk the x axis, all integers */
x0 = fix_int(x0);
x1 = fix_int(x1);
y0 = fix_int(y0);
y1 = fix_int(y1);
if (x0 > x1) {
t = x0;
x0 = x1;
x1 = t;
t = y0;
y0 = y1;
y1 = t;
t = i0;
i0 = i1;
i1 = t;
}
p = grd_bm.bits + grd_bm.row * y0; /* set canvas ptr */
di = fix_div((i1 - i0), dx);
if (y0 < y1) {
while (y0 <= y1) {
macro_plot_i(x0, p, fix_fint(i0));
x0++;
y0++;
p += grd_bm.row;
i0 += di;
}
} else {
while (y0 >= y1) {
macro_plot_i(x0, p, fix_fint(i0));
x0++;
y0--;
p -= grd_bm.row;
i0 += di;
}
}
}
@@ -0,0 +1,145 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8sply.c $
* $Revision: 1.1 $
* $Author: kevin $
* $Date: 1994/08/16 13:11:44 $
*
* Routines for drawing flat shaded polygons onto a flat 8 canvas.
*
* This file is part of the 2d library.
*/
#include "cnvdat.h"
#include "gente.h"
#include "poly.h"
#include "tlucdat.h"
#include "tmapint.h"
// prototypes
int gri_spoly_loop(grs_tmap_loop_info *ti);
void gri_spoly_init(grs_tmap_loop_info *ti);
void gri_clut_spoly_init(grs_tmap_loop_info *ti);
void gri_stpoly_init(grs_tmap_loop_info *ti);
void gri_clut_stpoly_init(grs_tmap_loop_info *ti);
int gri_spoly_loop(grs_tmap_loop_info *ti) {
int d;
fix i, di;
fix xl, xr;
uchar *ti_d;
fix ti_li, ti_ri;
xl = ti->left.x;
xr = ti->right.x;
ti_li = ti->left.i;
ti_ri = ti->right.i;
ti_d = ti->d;
do {
i = ti_li;
di = fix_div(ti_ri - i, xr - xl);
i += fix_mul(fix_ceil(xl) - xl, di);
if ((d = fix_cint(xr) - fix_cint(xl)) > 0) {
switch (ti->bm.hlog) {
int x;
case GRL_OPAQUE:
for (x = fix_cint(xl); x < fix_cint(xr); x++) {
ti_d[x] = fix_fint(i);
i += di;
}
break;
case GRL_CLUT:
for (x = fix_cint(xl); x < fix_cint(xr); x++) {
ti_d[x] = ti->clut[fix_fint(i)];
i += di;
}
break;
case GRL_TLUC8:
for (x = fix_cint(xl); x < fix_cint(xr); x++) {
ti_d[x] = tluc8stab[fix_light(i) + ti_d[x]];
i += di;
}
break;
case GRL_CLUT | GRL_TLUC8:
for (x = fix_cint(xl); x < fix_cint(xr); x++) {
ti_d[x] = ti->clut[tluc8stab[fix_light(i) + ti_d[x]]];
i += di;
}
break;
}
} else if (d < 0) {
return TRUE;
}
/* update span extrema and destination. */
ti_d += grd_bm.row;
xl += ti->left.dx;
xr += ti->right.dx;
ti_li += ti->left.di;
ti_ri += ti->right.di;
} while ((--(ti->n)) > 0);
ti->d = ti_d;
ti->left.x = xl;
ti->right.x = xr;
ti->left.i = ti_li;
ti->right.i = ti_ri;
return FALSE;
}
void gri_spoly_init(grs_tmap_loop_info *ti) {
ti->bm.hlog = GRL_OPAQUE;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_spoly_loop;
ti->top_edge_func = (void (*)())gri_ix_edge;
ti->bot_edge_func = (void (*)())gri_ix_edge;
}
void gri_clut_spoly_init(grs_tmap_loop_info *ti) {
ti->bm.hlog = GRL_CLUT;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_spoly_loop;
ti->top_edge_func = (void (*)())gri_ix_edge;
ti->bot_edge_func = (void (*)())gri_ix_edge;
}
void gri_stpoly_init(grs_tmap_loop_info *ti) {
if (tluc8stab != NULL)
ti->bm.hlog = GRL_TLUC8;
else
ti->bm.hlog = GRL_OPAQUE;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_spoly_loop;
ti->top_edge_func = (void (*)())gri_ix_edge;
ti->bot_edge_func = (void (*)())gri_ix_edge;
}
void gri_clut_stpoly_init(grs_tmap_loop_info *ti) {
if (tluc8stab != NULL)
ti->bm.hlog = GRL_CLUT | GRL_TLUC8;
else
ti->bm.hlog = GRL_CLUT;
ti->d = ti->y * grd_bm.row + grd_bm.bits;
ti->loop_func = (void (*)())gri_spoly_loop;
ti->top_edge_func = (void (*)())gri_ix_edge;
ti->bot_edge_func = (void (*)())gri_ix_edge;
}
@@ -0,0 +1,45 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8sub.c $
* $Revision: 1.2 $
* $Author: kaboom $
* $Date: 1993/10/08 01:15:35 $
*
* Sub bitmap routine for flat 8 bitmaps.
*
* This file is part of the 2d library.
*
* $Log: fl8sub.c $
* Revision 1.2 1993/10/08 01:15:35 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.1 1993/04/29 18:46:54 kaboom
* Initial revision
*
*/
#include "grs.h"
grs_bitmap *flat8_sub_bitmap(grs_bitmap *bm, short x, short y, short w, short h) {
bm->bits += y * bm->row + x;
bm->w = w;
bm->h = h;
return bm;
}
@@ -0,0 +1,140 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8tf.h $
* $Revision: 1.14 $
* $Author: kevin $
* $Date: 1994/10/25 16:51:42 $
*
* Table functions.
* Flat8 canvas.
*
* This file is part of the 2d library.
*
*/
#include "pertyp.h"
#include "tmapint.h"
/* pixel primitives */
extern void flat8_set_upixel(long color, short x, short y);
extern void flat8_clut_set_upixel(long color, short x, short y);
extern void flat8_xor_set_upixel(long color, short x, short y);
extern void flat8_blend_set_upixel(long color, short x, short y);
extern void flat8_solid_set_upixel(long color, short x, short y);
/* blit primitives */
extern void flat8_flat8_ubitmap(grs_bitmap *bm, short x, short y);
extern void flat8_tluc8_ubitmap(grs_bitmap *bm, short x, short y);
extern int gri_flat8_mask_bitmap(grs_bitmap *bm, short x, short y, grs_stencil *sten);
extern void gri_flat8_clut_ubitmap(grs_bitmap *bm, short x, short y, uchar *cl);
extern int gri_flat8_mask_fill_clut_bitmap(grs_bitmap *bm, short x, short y, grs_stencil *sten);
extern void gri_flat8_fill_clut_ubitmap(grs_bitmap *bm, short x, short y);
extern void gri_flat8_rsd8_ubitmap(grs_bitmap *bm, short x, short y);
extern int gri_flat8_rsd8_bitmap(grs_bitmap *bm, short x_left, short y_top);
/* inner loop initializers */
/* normal fill: */
extern void gri_trans_blend_clut_lin_umap_init(grs_tmap_loop_info *ti);
extern void gri_opaque_true_lin_umap_init();
extern void gri_opaque_clut_true_lin_umap_init();
extern void gri_opaque_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_lit_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_lit_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_clut_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_clut_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_floor_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_floor_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_lit_floor_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_lit_floor_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_clut_floor_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_clut_floor_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_wall_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_wall_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_lit_wall_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_lit_wall_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_clut_wall_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_clut_wall_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_wall1d_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_wall1d_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_clut_wall1d_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_lit_wall1d_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_lit_wall1d_umap_init(grs_tmap_loop_info *tli);
extern void gri_trans_clut_wall1d_umap_init(grs_tmap_loop_info *tli);
extern void gri_opaque_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_trans_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_opaque_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_trans_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_opaque_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_trans_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_opaque_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_trans_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_opaque_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_trans_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_opaque_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_trans_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern int gri_opaque_scale_umap_init(grs_tmap_loop_info *tli);
extern int gri_trans_scale_umap_init(grs_tmap_loop_info *tli, grs_vertex **vert);
extern int gri_opaque_clut_scale_umap_init(grs_tmap_loop_info *tli);
extern int gri_trans_clut_scale_umap_init(grs_tmap_loop_info *tli);
extern void gri_poly_init(grs_tmap_loop_info *ti);
extern void gri_spoly_init(grs_tmap_loop_info *ti);
extern void gri_cpoly_init(grs_tmap_loop_info *ti);
extern void gri_tpoly_init(grs_tmap_loop_info *ti);
extern void gri_stpoly_init(grs_tmap_loop_info *ti);
/* clut fill: */
extern void gri_clut_poly_init(grs_tmap_loop_info *ti);
extern void gri_clut_spoly_init(grs_tmap_loop_info *ti);
extern void gri_clut_cpoly_init(grs_tmap_loop_info *ti);
extern void gri_clut_tpoly_init(grs_tmap_loop_info *ti);
extern void gri_clut_stpoly_init(grs_tmap_loop_info *ti);
/* solid fill: */
extern void gri_solid_poly_init(grs_tmap_loop_info *ti);
extern void gri_trans_solid_lin_umap_init(grs_tmap_loop_info *ti);
extern void gri_trans_solid_floor_umap_init(grs_tmap_loop_info *ti);
extern void gri_trans_solid_wall_umap_init(grs_tmap_loop_info *ti);
extern void gri_trans_solid_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern void gri_trans_solid_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
extern int gri_opaque_solid_scale_umap_init(grs_tmap_loop_info *info, grs_vertex **vert);
extern int gri_trans_solid_scale_umap_init(grs_tmap_loop_info *tli, grs_vertex **vert);
/* translucent bitmaps */
extern void gri_tluc8_opaque_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_tluc8_trans_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_tluc8_opaque_lit_lin_umap_init();
extern void gri_tluc8_trans_lit_lin_umap_init();
extern void gri_tluc8_opaque_clut_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_tluc8_trans_clut_lin_umap_init(grs_tmap_loop_info *tli);
extern void gri_tluc8_opaque_scale_umap_init(grs_tmap_loop_info *tli);
extern void gri_tluc8_trans_scale_umap_init(grs_tmap_loop_info *tli);
extern void gri_tluc8_opaque_clut_scale_umap_init(grs_tmap_loop_info *tli);
extern void gri_tluc8_trans_clut_scale_umap_init(grs_tmap_loop_info *tli);
@@ -0,0 +1,79 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/fl8tl8.c $
* $Revision: 1.2 $
* $Author: baf $
* $Date: 1994/01/14 12:40:30 $
*
* Routines for drawing flat 8 bitmaps into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8tl8.c $
* Revision 1.2 1994/01/14 12:40:30 baf
* Lit translucency reform
*
* Revision 1.1 1993/12/01 21:17:31 baf
* Initial revision
*
*/
#include "bitmap.h"
#include "cnvdat.h"
#include "fl8tf.h"
#include "tluctab.h"
#include <string.h>
void flat8_tluc8_ubitmap(grs_bitmap *bm, short x, short y) {
uchar *src;
uchar *dst;
long w = bm->w;
long h = bm->h;
long i;
long grow = grd_bm.row;
long brow = bm->row;
src = bm->bits;
dst = grd_bm.bits + grow * y + x;
if (bm->flags & BMF_TRANS)
while (h--) {
for (i = 0; i < w; i++)
if (src[i] != 0) {
if (tluc8tab[src[i]] == NULL)
dst[i] = src[i];
else
dst[i] = tluc8tab[src[i]][dst[i]];
}
src += brow;
dst += grow;
}
else
while (h--) {
for (i = 0; i < w; i++) {
if (tluc8tab[src[i]] == NULL)
dst[i] = src[i];
else
dst[i] = tluc8tab[src[i]][dst[i]];
}
src += brow;
dst += grow;
}
}
@@ -0,0 +1,33 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
#ifdef __cplusplus
extern "C" {
#endif
extern fix fix_mul_asm_safe(fix a, fix b);
#ifdef __cplusplus
}
#endif
// InvDIv = 0 to use divs in mappers, !=0 to use inverse multiplies
#define InvDiv 1
// this macro does a safe divide on a light, which we can shift up for more
// precision
#define fix_mul_asm_safe_light(a, b) ((fix_mul_asm_safe(a, b) + 0x00FF) >> 8)
@@ -0,0 +1,305 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8tp.c $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/16 12:57:22 $
*
* full perspective texture mapper.
* scanline processors.
*
*/
#include "cnvdat.h"
#include "fl8tmapdv.h"
#include "pertyp.h"
#include "plytyp.h"
// prototypes
void gri_trans_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_trans_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_trans_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_trans_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
void gri_trans_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, y_cint;
uchar *p, temp_pix;
// locals used to speed PPC code
fix l_u, l_v, l_du, l_dv, l_y_fix, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_x, l_xl, l_xr, l_xr0, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_y;
uchar *bm_bits;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_y_fix = pi->y_fix;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_xr0 = pi->xr0;
l_x = pi->x;
l_xl = pi->xl;
l_xr = pi->xr;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_x * l_du;
l_v += l_x * l_dv;
y_cint = fix_int(l_y_fix);
if (l_scan_slope < 0)
gr_row = -gr_row;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
if (l_x < l_xl) {
fix test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
for (; l_x < l_xl; l_x++) {
if (test <= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = temp_pix; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtl;
} else
test += l_dyl;
p++;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_x < l_xr0; l_x++) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = temp_pix; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint)
p += gr_row;
p++;
l_u += l_du;
l_v += l_dv;
}
if (l_x < l_xr) {
fix test = l_x * l_dyr - y_cint * pi->dxr + pi->cr;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
for (; l_x < l_xr; l_x++) {
if (test >= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = temp_pix; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
p += gr_row;
test += l_dtr;
} else
test += l_dyr;
p++;
l_u += l_du;
l_v += l_dv;
}
}
pi->y_fix = l_y_fix;
pi->x = l_x;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
void gri_trans_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
register int k, x_cint;
// locals used to speed PPC code
fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_x;
uchar *bm_bits;
uchar *p, temp_pix;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dxr = pi->dxr;
l_x_fix = pi->x_fix;
l_y = pi->y;
l_yr = pi->yr;
l_yr0 = pi->yr0;
l_yl = pi->yl;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
#if InvDiv
k = fix_div(fix_make(1, 0), pi->denom);
l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
l_du = fix_mul_asm_safe(pi->dunum, k);
l_dv = fix_mul_asm_safe(pi->dvnum, k);
#else
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
#endif
l_u += l_y * l_du;
l_v += l_y * l_dv;
x_cint = fix_int(l_x_fix);
p = grd_bm.bits + x_cint + l_y * gr_row;
if (l_y < l_yl) {
fix test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
for (; l_y < l_yl; l_y++) {
if (test <= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = temp_pix; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtl;
p -= (temp_x - x_cint);
} else
test += l_dxl;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_y < l_yr0; l_y++) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = temp_pix; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint)
p -= (temp_x - x_cint);
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
if (l_y < l_yr) {
fix test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
p = grd_bm.bits + x_cint + l_y * gr_row;
for (; l_y < l_yr; l_y++) {
if (test >= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
temp_pix = bm_bits[k];
if (temp_pix != 0)
*p = temp_pix; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtr;
p -= (temp_x - x_cint);
} else
test += l_dxr;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
pi->x_fix = l_x_fix;
pi->y = l_y;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
extern void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
extern void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_trans_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_hscan;
ps->scanline_func = (void (*)())gri_trans_per_umap_hscan_scanline;
}
void gri_trans_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_vscan;
ps->scanline_func = (void (*)())gri_trans_per_umap_vscan_scanline;
}
@@ -0,0 +1,562 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
// Implementation solid transparent mappers
//
// This file is part of the 2d library.
//
#include "cnvdat.h"
#include "fl8tf.h"
#include "gente.h"
#include "poly.h"
#include "tmapint.h"
#include "vtab.h"
// prototypes
int gri_trans_solid_lin_umap_loop(grs_tmap_loop_info *tli);
int gri_trans_solid_floor_umap_loop(grs_tmap_loop_info *tli);
int gri_solid_wall_umap_loop(grs_tmap_loop_info *tli);
void gri_trans_solid_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
void gri_trans_solid_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
int gri_trans_solid_lin_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, du, dv, dx, d;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
int x;
uchar solid_color;
int t_xl, t_xr;
uchar *p_dest;
int32_t *t_vtab;
uchar *t_bits;
uchar *t_clut;
uchar t_wlog;
uint32_t t_mask;
int32_t gr_row;
uchar *start_pdest;
solid_color = tli->solid;
u = tli->left.u;
du = tli->right.u - u;
v = tli->left.v;
dv = tli->right.v - v;
dx = tli->right.x - tli->left.x;
t_vtab = tli->vtab;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
t_bits = tli->bm.bits;
gr_row = grd_bm.row;
start_pdest = grd_bm.bits + (gr_row * (tli->y));
do {
if ((d = fix_ceil(tli->right.x) - fix_ceil(tli->left.x)) > 0) {
d = fix_ceil(tli->left.x) - tli->left.x;
du = fix_div(du, dx);
dv = fix_div(dv, dx);
u += fix_mul(du, d);
v += fix_mul(dv, d);
// copy out tli-> stuff into locals
t_xl = fix_cint(tli->left.x);
t_xr = fix_cint(tli->right.x);
p_dest = start_pdest + t_xl;
if (tli->bm.hlog == GRL_TRANS) {
for (x = t_xl; x < t_xr; x++) {
if (t_bits[t_vtab[fix_fint(v)] + fix_fint(u)])
*p_dest = solid_color; // gr_fill_upixel(t_bits[k],x,y);
p_dest++;
u += du;
v += dv;
}
} else {
for (x = t_xl; x < t_xr; x++) {
if (t_bits[((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask])
*p_dest = solid_color; // gr_fill_upixel(t_bits[k],x,y);
p_dest++;
u += du;
v += dv;
}
}
} else if (d < 0)
return TRUE; /* punt this tmap */
u = (tli->left.u += tli->left.du);
tli->right.u += tli->right.du;
du = tli->right.u - u;
v = (tli->left.v += tli->left.dv);
tli->right.v += tli->right.dv;
dv = tli->right.v - v;
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
dx = tli->right.x - tli->left.x;
tli->y++;
start_pdest += gr_row;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
void gri_trans_solid_lin_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_trans_solid_lin_umap_loop;
tli->right_edge_func = (void (*)())gri_uvx_edge;
tli->left_edge_func = (void (*)())gri_uvx_edge;
}
int gri_trans_solid_floor_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, du, dv, dx, d;
uchar solid_color;
int x;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
int t_xl, t_xr, t_y, gr_row;
int32_t *t_vtab;
uchar *t_bits;
uchar *p_dest;
uchar temp_pix;
uchar t_wlog;
uint32_t t_mask;
solid_color = tli->solid;
u = fix_div(tli->left.u, tli->w);
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div(tli->left.v, tli->w);
dv = fix_div(tli->right.v, tli->w) - v;
dx = tli->right.x - tli->left.x;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
t_vtab = tli->vtab;
t_bits = tli->bm.bits;
gr_row = grd_bm.row;
do {
if ((d = fix_ceil(tli->right.x) - fix_ceil(tli->left.x)) > 0) {
d = fix_ceil(tli->left.x) - tli->left.x;
du = fix_div(du, dx);
u += fix_mul(du, d);
dv = fix_div(dv, dx);
v += fix_mul(dv, d);
// copy out tli-> stuff into locals
t_xl = fix_cint(tli->left.x);
t_xr = fix_cint(tli->right.x);
t_y = tli->y;
p_dest = grd_bm.bits + (grd_bm.row * t_y) + t_xl;
if (tli->bm.hlog == GRL_TRANS) {
for (x = t_xl; x < t_xr; x++) {
int k = t_vtab[fix_fint(v)] + fix_fint(u);
if (t_bits[k])
*p_dest = solid_color; // gr_fill_upixel(t_bits[k],x,t_y);
p_dest++;
u += du;
v += dv;
}
} else {
for (x = t_xl; x < t_xr; x++) {
int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
if (t_bits[k])
*p_dest = solid_color; // gr_fill_upixel(t_bits[k],x,t_y);
p_dest++;
u += du;
v += dv;
}
}
} else if (d < 0)
return TRUE; /* punt this tmap */
tli->w += tli->dw;
u = fix_div((tli->left.u += tli->left.du), tli->w);
tli->right.u += tli->right.du;
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div((tli->left.v += tli->left.dv), tli->w);
tli->right.v += tli->right.dv;
dv = fix_div(tli->right.v, tli->w) - v;
tli->left.x += tli->left.dx;
tli->right.x += tli->right.dx;
dx = tli->right.x - tli->left.x;
tli->y++;
} while (--(tli->n) > 0);
return FALSE; /* tmap OK */
}
void gri_trans_solid_floor_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_trans_solid_floor_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwx_edge;
tli->right_edge_func = (void (*)())gri_uvwx_edge;
}
int gri_solid_wall_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, du, dv, dy, d;
uchar solid_color;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
int t_yl, t_yr;
int32_t *t_vtab;
uchar *t_bits;
uchar *p_dest;
uchar *t_clut;
uchar t_wlog;
uint32_t t_mask;
int32_t gr_row;
int y;
solid_color = tli->solid;
u = fix_div(tli->left.u, tli->w);
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div(tli->left.v, tli->w);
dv = fix_div(tli->right.v, tli->w) - v;
dy = tli->right.y - tli->left.y;
t_bits = tli->bm.bits;
t_vtab = tli->vtab;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
gr_row = grd_bm.row;
// handle PowerPC loop
do {
if ((d = fix_ceil(tli->right.y) - fix_ceil(tli->left.y)) > 0) {
d = fix_ceil(tli->left.y) - tli->left.y;
du = fix_div(du, dy);
dv = fix_div(dv, dy);
u += fix_mul(du, d);
v += fix_mul(dv, d);
t_yl = fix_cint(tli->left.y);
t_yr = fix_cint(tli->right.y);
p_dest = grd_bm.bits + (gr_row * t_yl) + tli->x;
if (tli->bm.hlog == GRL_TRANS) {
for (y = t_yl; y < t_yr; y++) {
int k = t_vtab[fix_fint(v)] + fix_fint(u);
if (t_bits[k])
*p_dest = solid_color; // gr_fill_upixel(t_bits[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
} else {
for (y = t_yl; y < t_yr; y++) {
int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
if (t_bits[k])
*p_dest = solid_color; // gr_fill_upixel(t_bits[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
}
} else if (d < 0)
return TRUE; /* punt this tmap */
tli->w += tli->dw;
u = fix_div((tli->left.u += tli->left.du), tli->w);
tli->right.u += tli->right.du;
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div((tli->left.v += tli->left.dv), tli->w);
tli->right.v += tli->right.dv;
dv = fix_div(tli->right.v, tli->w) - v;
tli->left.y += tli->left.dy;
tli->right.y += tli->right.dy;
dy = tli->right.y - tli->left.y;
tli->x++;
} while (--(tli->n) > 0);
return FALSE;
}
void gri_trans_solid_wall_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_solid_wall_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwy_edge;
tli->right_edge_func = (void (*)())gri_uvwy_edge;
}
void gri_trans_solid_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
int y_cint;
uchar *p;
uchar solid_color;
// locals used to speed PPC code
fix l_u, l_v, l_du, l_dv, l_y_fix, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_x, l_xl, l_xr, l_xr0, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_y;
uchar *bm_bits;
solid_color = pi->fill_parm;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_y_fix = pi->y_fix;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_xr0 = pi->xr0;
l_x = pi->x;
l_xl = pi->xl;
l_xr = pi->xr;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
l_u += l_x * l_du;
l_v += l_x * l_dv;
y_cint = fix_int(l_y_fix);
if (l_scan_slope < 0)
gr_row = -gr_row;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
if (l_x < l_xl) {
fix test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
for (; l_x < l_xl; l_x++) {
if (test <= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
if (bm_bits[k])
*p = solid_color; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
test += l_dtl;
p += gr_row;
} else
test += l_dyl;
p++;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_x < l_xr0; l_x++) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
if (bm_bits[k])
*p = solid_color; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) // y_cint=fix_int((l_y_fix+=l_scan_slope));
{
temp_y -= y_cint;
p += gr_row;
}
p++;
l_u += l_du;
l_v += l_dv;
}
if (l_x < l_xr) {
fix test = l_x * l_dyr - y_cint * pi->dxr + pi->cr;
p = grd_bm.bits + l_x + y_cint * grd_bm.row;
for (; l_x < l_xr; l_x++) {
if (test >= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
if (bm_bits[k])
*p = solid_color; // gr_fill_upixel(bm_bits[k],l_x,y_cint);
}
temp_y = y_cint;
y_cint = fix_int(l_y_fix += l_scan_slope);
if (temp_y != y_cint) {
test += l_dtr;
p += gr_row;
} else
test += l_dyr;
p++;
l_u += l_du;
l_v += l_dv;
}
}
pi->y_fix = l_y_fix;
pi->x = l_x;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
void gri_trans_solid_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
int x_cint;
uchar solid_color;
// locals used to speed PPC code
fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr;
int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
int gr_row, temp_x;
uchar *bm_bits;
uchar *p;
solid_color = pi->fill_parm;
gr_row = grd_bm.row;
bm_bits = bm->bits;
l_dxr = pi->dxr;
l_x_fix = pi->x_fix;
l_y = pi->y;
l_yr = pi->yr;
l_yr0 = pi->yr0;
l_yl = pi->yl;
l_dyr = pi->dyr;
l_dtr = pi->dtr;
l_dyl = pi->dyl;
l_dxl = pi->dxl;
l_dtl = pi->dtl;
l_scan_slope = pi->scan_slope;
l_v_shift = pi->v_shift;
l_v_mask = pi->v_mask;
l_u_mask = pi->u_mask;
l_u = pi->u;
l_v = pi->v;
l_du = pi->du;
l_dv = pi->dv;
l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
l_u = pi->u0 + fix_div(pi->unum, pi->denom);
l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
l_du = fix_div(pi->dunum, pi->denom);
l_dv = fix_div(pi->dvnum, pi->denom);
l_u += l_y * l_du;
l_v += l_y * l_dv;
x_cint = fix_int(l_x_fix);
p = grd_bm.bits + x_cint + l_y * gr_row;
if (l_y < l_yl) {
fix test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
for (; l_y < l_yl; l_y++) {
if (test <= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
if (bm_bits[k])
*p = solid_color; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtl;
p -= (temp_x - x_cint);
} else
test += l_dxl;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
for (; l_y < l_yr0; l_y++) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
if (bm_bits[k])
*p = solid_color; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint)
p -= (temp_x - x_cint);
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
if (l_y < l_yr) {
fix test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
p = grd_bm.bits + x_cint + l_y * gr_row;
for (; l_y < l_yr; l_y++) {
if (test >= 0) {
int k = (l_u >> 16) & l_u_mask;
k += (l_v >> l_v_shift) & l_v_mask;
if (bm_bits[k])
*p = solid_color; // gr_fill_upixel(bm_bits[k],x_cint,l_y);
}
temp_x = x_cint;
x_cint = fix_int(l_x_fix += l_scan_slope);
if (temp_x != x_cint) {
test += l_dtr;
p -= (temp_x - x_cint);
} else
test += l_dxr;
p += gr_row;
l_u += l_du;
l_v += l_dv;
}
}
pi->x_fix = l_x_fix;
pi->y = l_y;
pi->u = l_u;
pi->v = l_v;
pi->du = l_du;
pi->dv = l_dv;
}
extern void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
extern void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
void gri_trans_solid_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_hscan;
ps->scanline_func = (void (*)())gri_trans_solid_per_umap_hscan_scanline;
}
void gri_trans_solid_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
ps->shell_func = (void (*)())gri_per_umap_vscan;
ps->scanline_func = (void (*)())gri_trans_solid_per_umap_vscan_scanline;
}
@@ -0,0 +1,134 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8vlin.c $
* $Revision: 1.7 $
* $Author: lmfeeney $
* $Date: 1994/08/12 01:10:20 $
*
* Routines for drawing vertical lines into a flat 8 canvas.
*
* This file is part of the 2d library.
*
* $Log: fl8vlin.c $
* Revision 1.7 1994/08/12 01:10:20 lmfeeney
* get fill/solid parm from right place
*
* Revision 1.6 1994/06/11 01:44:53 lmfeeney
* unclipped flat8 line drawer routines for each fill type
* added canvas values as parameters
*
* Revision 1.5 1993/10/19 09:51:05 kaboom
* Replaced #include <grd.h" with new headers split from grd.h.
*
* Revision 1.4 1993/10/08 01:15:38 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.3 1993/05/04 18:44:04 kaboom
* Changed vline to be inclusive of its endpoints.
*
* Revision 1.2 1993/03/02 19:42:08 kaboom
* Changed not to draw the bottommost pixel.
*
* Revision 1.1 1993/02/22 14:44:38 kaboom
* Initial revision
*/
#include "cnvdat.h"
#include "ctxmac.h"
#include "fill.h"
/* unclipped vertical line with integral coordinates. */
// MLA #pragma off (unreferenced)
/* clut should be in _ns everywhere, it doesn't need its own function */
void gri_flat8_uvline_ns(short x0, short y0, short y1, long c, long parm) {
uchar *p;
short t;
int grow = grd_bm.row;
if (y0 > y1) {
t = y0;
y0 = y1;
y1 = t;
}
if (gr_get_fill_type() == FILL_SOLID)
c = (uchar)parm;
p = grd_bm.bits + y0 * grow + x0;
for (; y0 <= y1; y0++) {
*p = c;
p += grow;
}
}
void gri_flat8_uvline_clut(short x0, short y0, short y1, long c, long parm) {
uchar *p;
short t;
int grow = grd_bm.row;
if (y0 > y1) {
t = y0;
y0 = y1;
y1 = t;
}
c = (long)(((uchar *)parm)[c]);
p = grd_bm.bits + y0 * grow + x0;
for (; y0 <= y1; y0++) {
*p = c;
p += grow;
}
}
void gri_flat8_uvline_xor(short x0, short y0, short y1, long c, long parm) {
uchar *p;
short t;
int grow = grd_bm.row;
if (y0 > y1) {
t = y0;
y0 = y1;
y1 = t;
}
p = grd_bm.bits + y0 * grow + x0;
for (; y0 <= y1; y0++) {
*p = *p ^ c;
p += grow;
}
}
/* punt */
void gri_flat8_uvline_blend(short x0, short y0, short y1, long c, long parm) {
uchar *p;
short t;
int grow = grd_bm.row;
if (y0 > y1) {
t = y0;
y0 = y1;
y1 = t;
}
p = grd_bm.bits + y0 * grow + x0;
for (; y0 <= y1; y0++) {
*p = c;
p += grow;
}
}
+407
View File
@@ -0,0 +1,407 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/genw.c $
* $Revision: 1.4 $
* $Author: kevin $
* $Date: 1994/08/16 12:50:15 $
*
* Routines to floor texture map a flat8 bitmap to a generic canvas.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "fl8tf.h"
#include "fl8tmapdv.h"
#include "gente.h"
#include "poly.h"
#include "tmapint.h"
#include "vtab.h"
#include <stdbool.h>
int gri_wall_umap_loop(grs_tmap_loop_info *tli);
int gri_wall_umap_loop_1D(grs_tmap_loop_info *tli);
int gri_wall_umap_loop(grs_tmap_loop_info *tli) {
fix u, v, du, dv, dy, d;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
int k, y;
uchar t_wlog;
uint32_t t_mask;
int32_t *t_vtab;
uchar *t_bits;
uchar *p_dest;
fix inv_dy;
uchar temp_pix;
uchar *t_clut;
int32_t gr_row;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(tli->left.u, inv_dy);
du = fix_mul_asm_safe(tli->right.u, inv_dy) - u;
v = fix_mul_asm_safe(tli->left.v, inv_dy);
dv = fix_mul_asm_safe(tli->right.v, inv_dy) - v;
#else
u = fix_div(tli->left.u, tli->w);
du = fix_div(tli->right.u, tli->w) - u;
v = fix_div(tli->left.v, tli->w);
dv = fix_div(tli->right.v, tli->w) - v;
#endif
dy = tli->right.y - tli->left.y;
t_vtab = tli->vtab;
t_bits = tli->bm.bits;
t_clut = tli->clut;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
gr_row = grd_bm.row;
do {
if ((d = fix_ceil(tli->right.y) - fix_ceil(tli->left.y)) > 0) {
d = fix_ceil(tli->left.y) - tli->left.y;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0), dy);
du = fix_mul_asm_safe(du, inv_dy);
dv = fix_mul_asm_safe(dv, inv_dy);
#else
du = fix_div(du, dy);
dv = fix_div(dv, dy);
#endif
u += fix_mul(du, d);
v += fix_mul(dv, d);
p_dest = grd_bm.bits + (gr_row * fix_cint(tli->left.y)) + tli->x;
y = fix_cint(tli->right.y) - fix_cint(tli->left.y);
switch (tli->bm.hlog) {
case GRL_OPAQUE:
for (; y > 0; y--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
*p_dest = t_bits[k]; // gr_fill_upixel(t_bits[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
case GRL_TRANS:
for (; y > 0; y--) {
temp_pix = t_bits[t_vtab[fix_fint(v)] + fix_fint(u)];
if (temp_pix != 0)
*p_dest = temp_pix; // gr_fill_upixel(t_bits[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_LOG2:
for (; y > 0; y--) {
*p_dest =
t_bits[((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask]; // gr_fill_upixel(t_bits[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_LOG2:
for (; y > 0; y--) {
temp_pix = t_bits[((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask];
if (temp_pix != 0)
*p_dest = temp_pix; // gr_fill_upixel(t_bits[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_CLUT:
for (; y > 0; y--) {
*p_dest =
t_clut[t_bits[t_vtab[fix_fint(v)] + fix_fint(u)]]; // gr_fill_upixel(t_clut[t_bits[k]],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_CLUT:
for (; y > 0; y--) {
k = t_vtab[fix_fint(v)] + fix_fint(u);
k = t_bits[k];
if (k != 0)
*p_dest = t_clut[k]; // gr_fill_upixel(t_clut[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
case GRL_OPAQUE | GRL_LOG2 | GRL_CLUT:
for (; y > 0; y--) {
*p_dest = t_clut[t_bits[((fix_fint(v) << t_wlog) + fix_fint(u)) &
t_mask]]; // gr_fill_upixel(t_clut[t_bits[k]],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
case GRL_TRANS | GRL_LOG2 | GRL_CLUT:
for (; y > 0; y--) {
k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
k = t_bits[k];
if (k != 0)
*p_dest = t_clut[k]; // gr_fill_upixel(t_clut[k],t_x,y);
p_dest += gr_row;
u += du;
v += dv;
}
break;
}
} else if (d < 0)
return TRUE; /* punt this tmap */
tli->w += tli->dw;
// figure out new left u & v & i
inv_dy = 0;
k = tli->left.u + tli->left.du;
y = tli->left.v + tli->left.dv;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(k, inv_dy);
v = fix_mul_asm_safe(y, inv_dy);
#else
u = fix_div(k, tli->w);
v = fix_div(y, tli->w);
#endif
tli->left.u = k;
tli->left.v = y;
// figure out new right u & v & i
k = tli->right.u + tli->right.du;
y = tli->right.v + tli->right.dv;
#if InvDiv
du = fix_mul_asm_safe(k, inv_dy) - u;
dv = fix_mul_asm_safe(y, inv_dy) - v;
#else
du = fix_div(k, tli->w) - u;
dv = fix_div(y, tli->w) - v;
#endif
tli->right.u = k;
tli->right.v = y;
tli->left.y += tli->left.dy;
tli->right.y += tli->right.dy;
dy = tli->right.y - tli->left.y;
tli->x++;
} while (--(tli->n) > 0);
return false;
}
void gri_trans_wall_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS;
}
tli->loop_func = (void (*)())gri_wall_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwy_edge;
tli->right_edge_func = (void (*)())gri_uvwy_edge;
}
void gri_opaque_wall_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE;
}
tli->loop_func = (void (*)())gri_wall_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwy_edge;
tli->right_edge_func = (void (*)())gri_uvwy_edge;
}
void gri_trans_clut_wall_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_TRANS | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_TRANS | GRL_CLUT;
}
tli->loop_func = (void (*)())gri_wall_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwy_edge;
tli->right_edge_func = (void (*)())gri_uvwy_edge;
}
void gri_opaque_clut_wall_umap_init(grs_tmap_loop_info *tli) {
if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2 | GRL_CLUT;
} else {
tli->vtab = gr_make_vtab(&(tli->bm));
tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
}
tli->loop_func = (void (*)())gri_wall_umap_loop;
tli->left_edge_func = (void (*)())gri_uvwy_edge;
tli->right_edge_func = (void (*)())gri_uvwy_edge;
}
/*extern "C"
{
extern int HandleWallLoop1D_PPC(grs_tmap_loop_info *tli,
fix u, fix v, fix dv, fix dy,
uchar *t_clut, int32_t *t_vtab, uchar *o_bits,
int32_t gr_row, uint32_t t_mask, uint32_t t_wlog);
}*/
int HandleWallLoop1D_C(grs_tmap_loop_info *tli, fix u, fix v, fix dv, fix dy, uchar *t_clut, int32_t *t_vtab,
uchar *o_bits, int32_t gr_row, uint32_t t_mask, uint32_t t_wlog) {
register int k, y;
register fix inv_dy;
register uchar *grd_bits, *p_dest, *t_bits;
register fix ry, ly;
ry = tli->right.y;
ly = tli->left.y;
grd_bits = grd_bm.bits + tli->x;
tli->x += tli->n;
do {
if ((k = fix_ceil(ry) - fix_ceil(ly)) > 0) {
k = fix_ceil(ly) - ly;
dv = fix_div(dv, dy);
v += fix_mul(dv, k);
p_dest = grd_bits + (gr_row * fix_cint(ly));
y = fix_cint(ry) - fix_cint(ly);
t_bits = o_bits + fix_fint(u);
for (; y > 0; y--) {
k = ((fix_fint(v) << t_wlog)) & t_mask;
*p_dest = t_clut[t_bits[k]]; // gr_fill_upixel(t_clut[t_bits[k]],t_x,y);
v += dv;
p_dest += gr_row;
}
} else if (k < 0)
return TRUE; // punt this tmap
tli->w += tli->dw;
// figure out new left u & v
k = tli->left.u + tli->left.du;
y = tli->left.v + tli->left.dv;
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(k, inv_dy);
v = fix_mul_asm_safe(y, inv_dy);
tli->left.u = k;
tli->left.v = y;
// figure out new right u & v
tli->right.u += tli->right.du;
y = tli->right.v + tli->right.dv;
dv = fix_mul_asm_safe(y, inv_dy) - v;
tli->right.v = y;
ly += tli->left.dy;
ry += tli->right.dy;
dy = ry - ly;
grd_bits++;
} while (--(tli->n) > 0);
tli->right.y = ry;
tli->left.y = ly;
return false;
}
// ==================================================================
// 1D versions
int gri_wall_umap_loop_1D(grs_tmap_loop_info *tli) {
fix u, v, dv, dy, d;
// locals used to store copies of tli-> stuff, so its in registers on the PPC
int k, y;
uchar t_wlog;
uint32_t t_mask;
int32_t *t_vtab;
uchar *t_bits, *o_bits;
uchar *p_dest;
fix inv_dy;
uchar temp_pix;
uchar *t_clut;
int32_t gr_row;
#if InvDiv
inv_dy = fix_div(fix_make(1, 0), tli->w);
u = fix_mul_asm_safe(tli->left.u, inv_dy);
v = fix_mul_asm_safe(tli->left.v, inv_dy);
dv = fix_mul_asm_safe(tli->right.v, inv_dy) - v;
#else
u = fix_div(tli->left.u, tli->w);
v = fix_div(tli->left.v, tli->w);
dv = fix_div(tli->right.v, tli->w) - v;
#endif
dy = tli->right.y - tli->left.y;
t_vtab = tli->vtab;
o_bits = tli->bm.bits;
t_clut = tli->clut;
t_mask = tli->mask;
t_wlog = tli->bm.wlog;
gr_row = grd_bm.row;
return HandleWallLoop1D_C(tli, u, v, dv, dy, t_clut, t_vtab, o_bits, gr_row, t_mask, t_wlog);
}
void gri_opaque_clut_wall1d_umap_init(grs_tmap_loop_info *tli) {
// MLA - Wall1d is always log2
/* if ((tli->bm.row==(1<<tli->bm.wlog)) &&
(tli->bm.h==(1<<tli->bm.hlog))) {*/
tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
tli->bm.hlog = GRL_OPAQUE | GRL_LOG2 | GRL_CLUT;
/* } else {
tli->vtab=gr_make_vtab(&(tli->bm));
tli->bm.hlog=GRL_OPAQUE|GRL_CLUT;
}*/
tli->loop_func = (void (*)())gri_wall_umap_loop_1D;
tli->left_edge_func = (void (*)())gri_uvwy_edge;
tli->right_edge_func = (void (*)())gri_uvwy_edge;
}
@@ -0,0 +1,87 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8wclin.c $
* $Revision: 1.3 $
* $Author: kevin $
* $Date: 1994/10/17 15:00:00 $
*
* Routines to draw wire polys.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "plytyp.h"
#include "scrdat.h"
#define gr_get_ipal_index(r, g, b) (long)((((r) >> 19) & 0x1f) | (((g) >> 14) & 0x3e0) | (((b) >> 9) & 0x7c00))
#define do_hline_inc_x \
do { \
c = grd_ipal[gr_get_ipal_index(r0, g0, b0)]; \
p[x] = c; \
r0 += dr, g0 += dg, b0 += db; \
x++; \
} while (x < x_new)
#define do_hline_dec_x \
if (x == x_new) { \
c = grd_ipal[gr_get_ipal_index(r0, g0, b0)]; \
p[x] = c; \
r0 += dr, g0 += dg, b0 += db; \
} else \
do { \
x--; \
c = grd_ipal[gr_get_ipal_index(r0, g0, b0)]; \
p[x] = c; \
r0 += dr, g0 += dg, b0 += db; \
} while (x > x_new)
// MLA #pragma off (unreferenced)
void gri_flat8_wire_poly_ucline_norm(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
#include "fl8wclin.h"
}
// MLA #pragma on (unreferenced)
#undef do_hline_inc_x
#define do_hline_inc_x \
do { \
c = grd_ipal[gr_get_ipal_index(r0, g0, b0)]; \
p[x] = clut[c]; \
r0 += dr, g0 += dg, b0 += db; \
x++; \
} while (x < x_new)
#undef do_hline_dec_x
#define do_hline_dec_x \
if (x == x_new) { \
c = grd_ipal[gr_get_ipal_index(r0, g0, b0)]; \
p[x] = clut[c]; \
r0 += dr, g0 += dg, b0 += db; \
} else \
do { \
x--; \
c = grd_ipal[gr_get_ipal_index(r0, g0, b0)]; \
p[x] = clut[c]; \
r0 += dr, g0 += dg, b0 += db; \
} while (x > x_new)
void gri_flat8_wire_poly_ucline_clut(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
uchar *clut = (uchar *)parm;
#include "fl8wclin.h"
}
@@ -0,0 +1,116 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8wclin.h $
* $Revision: 1.1 $
* $Author: kevin $
* $Date: 1994/08/04 09:58:31 $
*
* Main shell for drawing wire poly rgb lines.
*
* This file is part of the 2d library.
*
*/
/* don't try to use this other than in fl8wclin.c */
int d, y, y_max, x, x_new;
fix x0, y0, r0, b0, g0;
fix x1, y1, r1, b1, g1;
fix dr, dg, db, x_fix, dx;
uchar *p;
if (v1->y > v0->y) {
y = fix_cint(v0->y);
y_max = fix_cint(v1->y);
} else {
y = fix_cint(v1->y);
y_max = fix_cint(v0->y);
}
p = grd_bm.bits + y * grd_bm.row;
/* horizontal? */
if (y_max - y <= 1) {
if (v1->x > v0->x) {
x_new = fix_cint(v1->x), x = fix_cint(v0->x);
r0 = fix_make(v0->u, 0), g0 = fix_make(v0->v, 0), b0 = fix_make(v0->w, 0);
r1 = fix_make(v1->u, 0), g1 = fix_make(v1->v, 0), b1 = fix_make(v1->w, 0);
} else {
x_new = fix_cint(v0->x), x = fix_cint(v1->x);
r0 = fix_make(v1->u, 0), g0 = fix_make(v1->v, 0), b0 = fix_make(v1->w, 0);
r1 = fix_make(v0->u, 0), g1 = fix_make(v0->v, 0), b1 = fix_make(v0->w, 0);
}
d = x_new - x;
if (d > 0) {
dr = (r1 - r0) / d;
dg = (g1 - g0) / d;
db = (b1 - b0) / d;
do_hline_inc_x;
}
return;
}
/* not horizontal */
if (v1->y > v0->y) {
y0 = v0->y, x0 = v0->x;
r0 = fix_make(v0->u, 0), g0 = fix_make(v0->v, 0), b0 = fix_make(v0->w, 0);
y1 = v1->y, x1 = v1->x;
r1 = fix_make(v1->u, 0), g1 = fix_make(v1->v, 0), b1 = fix_make(v1->w, 0);
} else {
y1 = v0->y, x1 = v0->x;
r1 = fix_make(v0->u, 0), g1 = fix_make(v0->v, 0), b1 = fix_make(v0->w, 0);
y0 = v1->y, x0 = v1->x;
r0 = fix_make(v1->u, 0), g0 = fix_make(v1->v, 0), b0 = fix_make(v1->w, 0);
}
dx = fix_div(x1 - x0, y1 - y0);
if (fix_abs(dx) > FIX_UNIT) {
d = fix_cint(x1) - fix_cint(x0);
if (d < 0)
d = -d;
} else {
d = y_max - y;
}
dr = (r1 - r0) / d;
dg = (g1 - g0) / d;
db = (b1 - b0) / d;
x = fix_cint(x0);
x_fix = x0 + fix_mul(fix_ceil(y0) - y0, dx);
x_new = fix_cint(x_fix);
/* draw line */
if (dx >= 0) {
do_hline_inc_x;
do {
x = x_new;
x_new = fix_cint(x_fix += dx);
do_hline_inc_x;
p += grd_bm.row;
} while ((++y) < y_max - 1);
x = x_new;
x_new = fix_cint(x1);
do_hline_inc_x;
} else {
do {
do_hline_dec_x;
x_new = fix_cint(x_fix += dx);
p += grd_bm.row;
} while ((++y) < y_max - 1);
x_new = fix_cint(x1);
do_hline_dec_x;
}
@@ -0,0 +1,116 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/fl8wlin.c $
* $Revision: 1.1 $
* $Author: kevin $
* $Date: 1994/08/04 09:53:09 $
*
* Routines to draw wire polys.
*
* This file is part of the 2d library.
*
*/
#include "cnvdat.h"
#include "ctxmac.h"
#include "fill.h"
#include "plytyp.h"
#define gr_get_ipal_index(r, g, b) (long)((((r) >> 19) & 0x1f) | (((g) >> 14) & 0x3e0) | (((b) >> 9) & 0x7c00))
#define do_hline_inc_x \
do { \
p[x] = c; \
x++; \
} while (x < x_new)
#define do_hline_dec_x \
if (x == x_new) { \
p[x] = c; \
} else \
do { \
x--; \
p[x] = c; \
} while (x > x_new)
void gri_flat8_wire_poly_uline(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
int y, y_max, x, x_new;
fix x0, y0;
fix x1, y1;
fix x_fix, dx;
uchar *p;
if (gr_get_fill_type() == FILL_SOLID)
c = (uchar)parm;
else if (gr_get_fill_type() == FILL_CLUT)
c = ((uchar *)parm)[c];
if (v1->y > v0->y) {
y = fix_cint(v0->y);
y_max = fix_cint(v1->y);
} else {
y = fix_cint(v1->y);
y_max = fix_cint(v0->y);
}
p = grd_bm.bits + y * grd_bm.row;
/* horizontal? */
if (y_max - y <= 1) {
if (v1->x > v0->x) {
x_new = fix_cint(v1->x), x = fix_cint(v0->x);
} else {
x_new = fix_cint(v0->x), x = fix_cint(v1->x);
}
do_hline_inc_x;
return;
}
/* not horizontal */
if (v1->y > v0->y) {
y0 = v0->y, x0 = v0->x;
y1 = v1->y, x1 = v1->x;
} else {
y1 = v0->y, x1 = v0->x;
y0 = v1->y, x0 = v1->x;
}
dx = fix_div(x1 - x0, y1 - y0);
x = fix_cint(x0);
x_fix = x0 + fix_mul(fix_ceil(y0) - y0, dx);
x_new = fix_cint(x_fix);
/* draw line */
if (dx >= 0) {
do_hline_inc_x;
do {
x = x_new;
x_new = fix_cint(x_fix += dx);
do_hline_inc_x;
p += grd_bm.row;
} while ((++y) < y_max - 1);
x = x_new;
x_new = fix_cint(x1);
do_hline_inc_x;
} else {
do {
do_hline_dec_x;
x_new = fix_cint(x_fix += dx);
p += grd_bm.row;
} while ((++y) < y_max - 1);
x_new = fix_cint(x1);
do_hline_dec_x;
}
}
@@ -0,0 +1,306 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/flat8.h $
* $Revision: 1.50 $
* $Author: kevin $
* $Date: 1994/08/16 15:31:34 $
*
* Prototypes for routines for drawing into flat8 bitmaps.
*
* This file is part of the 2d library.
*
* $Log: flat8.h $
* Revision 1.50 1994/08/16 15:31:34 kevin
* removed obsolete scaler function declarations.
*
* Revision 1.49 1994/07/18 17:05:21 kevin
* Moved temp_ functions to general.h.
*
* Revision 1.48 1994/04/09 07:19:32 lmfeeney
* added routines for scaled mono bitmaps
*
* Revision 1.47 1994/03/29 17:31:21 kevin
* Added doofy floor and wall mapper chaining primitives.
*
* Revision 1.46 1994/03/15 13:07:34 kevin
* Added clut_bitmap procedures.
*
* Revision 1.45 1994/03/14 17:58:22 kevin
* Added declarations for bitmap doubling routines.
*
* Revision 1.44 1994/02/26 22:50:39 kevin
* Fixed declarations for texture mapping functions.
*
* Revision 1.43 1994/02/24 22:22:33 baf
* Added tluc8 clut scaler.
*
* Revision 1.42 1994/02/14 20:38:35 baf
* Added dummy parameter to cpoly and spoly routines, for uniformity needed by
* 3D.
*
* Revision 1.41 1994/01/17 22:13:16 baf
* Redid tluc8 spolys (again).
*
* Revision 1.40 1994/01/13 12:18:47 kevin
* Added new scaling primitives.
*
* Revision 1.39 1994/01/05 04:30:45 kevin
* new lit linear mapper.
*
* Revision 1.38 1994/01/03 23:32:03 kevin
* Added prototypes for new temorary chaining primitives.
*
* Revision 1.37 1993/12/30 11:04:28 baf
* non/span solid filled polygons
*
* Revision 1.36 1993/12/28 22:04:29 baf
* Added solid RSD stuff
*
* Revision 1.35 1993/12/04 17:29:57 kevin
* Added clut_per_umap declaration.
*
* Revision 1.34 1993/12/04 12:14:19 kevin
* Added declarations for clut wall and floor mappers.
* ..
*
* Revision 1.33 1993/12/01 21:18:56 baf
* Added some tluc8 stuff.
*
* Revision 1.32 1993/11/24 01:49:05 kevin
* Added declarations for wall and floor texture mapping primitives.
*
* Revision 1.31 1993/11/18 23:31:25 kevin
* Changed flat8 perspective mapper names in honor of installing
* working versions of eric's spiffy algorithm.
*
* Revision 1.30 1993/11/10 22:46:55 kevin
* Added declaration for flat8 clut scaler.
*
* Revision 1.29 1993/10/26 02:09:10 kevin
* Added prototypes for rsd bitmap scaling and clut-scaling primitives.
*
* Revision 1.28 1993/10/20 15:20:29 kaboom
* Updated prototypes for spoly routines.
*
* Revision 1.27 1993/10/19 09:56:04 kaboom
* Updated names of polygon routines.
*
* Revision 1.26 1993/10/08 00:37:46 kevin
* Added declaration for clut linear mapper optimized for flat8 canvasses.
*
* Revision 1.25 1993/10/06 13:28:30 kevin
* Added clut version of hflip routine.
*
* Revision 1.24 1993/10/02 01:58:13 kaboom
* Put accidentally deleted prototype for flat8_lin_lit_utmap() back in.
*
* Revision 1.23 1993/10/01 16:02:12 kaboom
* Updated names for linear and perspective mappers.
*
* Revision 1.22 1993/09/08 21:48:34 kaboom
* Added prototype for flat8_lin_lit_utmap().
*
* Revision 1.21 1993/09/07 17:45:18 kaboom
* Renamed flat8_lin_umap to flat8_flat8_lin_umap().
*
* Revision 1.20 1993/09/02 20:04:44 kaboom
* Added prototypes for 24-bit pixel routines.
*
* Revision 1.19 1993/08/10 19:06:30 kaboom
* Added prototype for flat8_lit_utmap.
*
* Revision 1.18 1993/08/05 20:07:09 jaemz
* Added fl8ntrp2 and fl8fltr2
*
* Revision 1.17 1993/07/01 22:11:05 spaz
* Added prototypes for fl8clin, fl8slin
*
* Revision 1.16 1993/06/14 14:09:38 kaboom
* Added prototypes for new lin_{u}map and lin_lit_lin_{u}map routines.
*
* Revision 1.15 1993/06/06 15:10:56 kaboom
* Added prototype for flat8_hflip_flat8_ubitmap().
*
* Revision 1.14 1993/05/03 13:50:16 kaboom
* Moved declarations for span rendering routines to different file.
*
* Revision 1.13 1993/03/29 18:29:54 kaboom
* Removed convex_ from polygon scanner names.
*
* Revision 1.12 1993/03/02 19:44:55 kaboom
* Took out prototype for flat8_int_uline().
*
* Revision 1.11 1993/02/26 17:51:53 kaboom
* Added prototype for flat8_fix_convex_upoly.
*
* Revision 1.10 1993/02/25 12:58:54 kaboom
* Added prototypes for flat 8 Gouraud shaders.
*
* Revision 1.9 1993/02/24 11:02:47 kaboom
* Added prototypes for more span functions.
*
* Revision 1.8 1993/02/22 20:31:28 kaboom
* Added prototypes for flat 8 span routines.
*
* Revision 1.7 1993/02/16 14:30:33 kaboom
* Added prototype for flat8_urect().
*
* Revision 1.6 1993/01/07 21:04:21 kaboom
* Moved declaration for flat8_func here.
*
* Revision 1.5 1992/12/30 15:11:51 kaboom
* Added prototypes for flat8_calc_vram() and flat8_calc_row().
*
* Revision 1.4 1992/12/14 18:12:45 kaboom
* Added prototype for flat8_sub_bm().
*
* Revision 1.3 1992/12/11 13:19:29 kaboom
* Added prototype for flat8_get_flat8_ubitmap.
*
* Revision 1.2 1992/11/19 09:15:16 kaboom
* Corrected typo---flat8_upoint occurred twice.
*
* Revision 1.1 1992/11/19 02:34:30 kaboom
* Initial revision
*/
#ifndef __FLAT8_H
#define __FLAT8_H
#include "grs.h"
#include "plytyp.h"
#include "tmapint.h"
/* 8-bit pixel prototypes. */
extern void flat8_set_upixel(long color, short x, short y);
extern int flat8_set_pixel(long color, short x, short y);
extern long flat8_get_upixel(short x, short y);
extern long flat8_get_pixel(short x, short y);
/* 24-bit pixel prototypes. */
extern void flat8_set_upixel24(long color, short x, short y);
extern int flat8_set_pixel24(long color, short x, short y);
extern long flat8_get_upixel24(short x, short y);
extern long flat8_get_pixel24(short x, short y);
/* straight, rectangular-type primitives. */
extern void flat8_clear(long color);
extern void flat8_upoint(short x, short y);
extern int flat8_point(short x, short y);
extern void flat8_uhline(short x0, short y0, short x1);
extern void flat8_uvline(short x0, short y0, short y1);
extern void flat8_urect(short left, short top, short right, short bot);
/* fixed-point rendering-type primitives. */
extern void flat8_fix_uline(fix x0, fix y0, fix x1, fix y1);
extern void flat8_fix_usline(fix x0, fix y0, fix i0, fix x1, fix y1, fix i1);
extern void flat8_fix_ucline(fix x0, fix y0, grs_rgb c0, fix x1, fix y1, grs_rgb c1);
extern void flat8_upoly(long c, int n, grs_vertex **vpl);
extern void flat8_uspoly(long c, int n, grs_vertex **vpl);
extern void flat8_ucpoly(long c, int n, grs_vertex **vpl);
extern void flat8_interp2_ubitmap(grs_bitmap *bm);
extern void flat8_filter2_ubitmap(grs_bitmap *bm);
extern void flat8_tluc8_upoly(long c, int n, grs_vertex **vpl);
extern void flat8_tluc8_uspoly(long c, int n, grs_vertex **vpl);
extern void flat8_flat8_lin_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern void flat8_lit_lin_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern void flat8_clut_lin_umap(grs_bitmap *bm, int n, grs_vertex **vpl, uchar *cl);
extern void flat8_flat8_solid_lin_umap(grs_bitmap *bm, int n, grs_vertex **vpl, int c);
extern void flat8_flat8_wall_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern void flat8_flat8_lit_wall_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern void flat8_flat8_clut_wall_umap(grs_bitmap *bm, int n, grs_vertex **vpl, uchar *cl);
extern void flat8_flat8_floor_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern void flat8_flat8_lit_floor_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern void flat8_flat8_clut_floor_umap(grs_bitmap *bm, int n, grs_vertex **vpl, uchar *cl);
extern int flat8_flat8_per_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern int flat8_flat8_lit_per_umap(grs_bitmap *bm, int n, grs_vertex **vpl);
extern int flat8_flat8_clut_per_umap(grs_bitmap *bm, int n, grs_vertex **vpl, uchar *cl);
extern int flat8_flat8_solid_per_umap(grs_bitmap *bm, int n, grs_vertex **vpl, int c);
extern void flat8_lin_lit_utmap(int n, fix *vlist, grs_bitmap *bm, fix *m, fix *l);
extern void flat8_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern int flat8_scale_bitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern void flat8_mono_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern int flat8_mono_scale_bitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern void flat8_rsd8_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern int flat8_rsd8_scale_bitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern void flat8_flat8_clut_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h, uchar *cl);
extern void flat8_rsd8_clut_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h, uchar *cl);
extern int flat8_rsd8_clut_scale_bitmap(grs_bitmap *bm, short x, short y, short w, short h, uchar *cl);
extern void flat8_rsd8_scale_solid_ubitmap(grs_bitmap *bm, short x, short y, short w, short h, int c);
extern int flat8_rsd8_scale_solid_bitmap(grs_bitmap *bm, short x, short y, short w, short h, int c);
extern void flat8_tluc8_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern int flat8_tluc8_scale_bitmap(grs_bitmap *bm, short x, short y, short w, short h);
extern void flat8_tluc8_clut_scale_ubitmap(grs_bitmap *bm, short x, short y, short w, short h, uchar *cl);
extern int flat8_tluc8_clut_scale_bitmap(grs_bitmap *bm, short x, short y, short w, short h, uchar *cl);
// internal scaler/mapper prototypes
int gri_opaque_solid_scale_umap_init(grs_tmap_loop_info *info, grs_vertex **vert);
int gri_trans_scale_umap_init(grs_tmap_loop_info *, grs_vertex **);
int gri_trans_solid_scale_umap_init(grs_tmap_loop_info *info, grs_vertex **vert);
int gri_opaque_scale_umap_init(grs_tmap_loop_info *tli);
int gri_trans_clut_scale_umap_init(grs_tmap_loop_info *tli);
int gri_opaque_clut_scale_umap_init(grs_tmap_loop_info *tli);
/* bitmap drawing functions. */
extern void flat8_mono_ubitmap(grs_bitmap *bm, short x, short y);
extern void flat8_flat8_ubitmap(grs_bitmap *bm, short x, short y);
extern void flat8_rsd8_ubitmap(grs_bitmap *bm, short x, short y);
extern void flat8_tluc8_ubitmap(grs_bitmap *bm, short x, short y);
extern int flat8_rsd8_bitmap(grs_bitmap *bm, short x, short y);
extern void flat8_flat8_clut_ubitmap(grs_bitmap *bm, short x, short y, uchar *cl);
extern void flat8_rsd8_solid_ubitmap(grs_bitmap *bm, short x, short y, int c);
extern int flat8_rsd8_solid_bitmap(grs_bitmap *bm, short x, short y, int c);
/* bitmap get routines. */
extern void flat8_get_flat8_ubitmap(grs_bitmap *bm, short x, short y);
/* bitmap horizontal flip routines. */
extern void flat8_hflip_flat8_ubitmap(grs_bitmap *bm, short x, short y);
/* bitmap color lookup table horizontal flip routines. */
extern void flat8_clut_hflip_flat8_ubitmap(grs_bitmap *bm, short x, short y, uchar *cl);
/* device-specific routines. */
extern short flat8_calc_row(short w);
extern grs_bitmap *flat8_sub_bitmap(grs_bitmap *bm, short x, short y, short w, short h);
/* bitmap doubling routines. */
extern void flat8_flat8_h_double_ubitmap(grs_bitmap *bm);
extern void flat8_flat8_smooth_h_double_ubitmap(grs_bitmap *srcb, grs_bitmap *dst);
extern void flat8_flat8_smooth_hv_double_ubitmap(grs_bitmap *src, grs_bitmap *dst);
extern void flat8_flat8_v_double_ubitmap(grs_bitmap *bm);
extern void flat8_flat8_hv_double_ubitmap(grs_bitmap *bm);
extern void flat8_flat8_smooth_v_double_ubitmap(grs_bitmap *bm);
#endif /* !__FLAT8_H */
+53
View File
@@ -0,0 +1,53 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grbm.h $
* $Revision: 1.4 $
* $Author: kaboom $
* $Date: 1993/10/19 10:15:22 $
*
* Dispatch macros for utility functions.
*
* This file is part of the 2d library.
*
* $Log: grbm.h $
* Revision 1.4 1993/10/19 10:15:22 kaboom
* Now includes tabdat.h.
*
* Revision 1.3 1993/10/08 01:15:55 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.2 1993/06/03 15:10:15 kaboom
* Now uses the grd_pixel_table to call bitmap utility functions.
*
* Revision 1.1 1993/04/29 18:35:01 kaboom
* Initial revision
*/
#ifndef __GRBM_H
#define __GRBM_H
#include "icanvas.h"
#include "tabdat.h"
#define gr_calc_row(w) \
((short (*)(short _w)) grd_pixel_table[CALC_ROW])(w)
#define gr_sub_bitmap(bm, x, y, w, h) \
((grs_bitmap *(*)(grs_bitmap *_bm,short _x,short _y,short _w,short _h)) \
grd_pixel_table[SUB_BITMAP])(bm, x, y, w, h)
#endif /* !__GRBM_H */
+92
View File
@@ -0,0 +1,92 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grcbm.h $
* $Revision: 1.1 $
* $Author: kevin $
* $Date: 1994/03/15 13:09:57 $
*
* Dispatch macros for bitmap draw functions.
*
* This file is part of the 2d library.
*
* $Log: grcbm.h $
* Revision 1.1 1994/03/15 13:09:57 kevin
* Initial revision
*
* Revision 1.5 1993/12/01 21:27:36 baf
* Added macros for translucent/8 bitmaps.
*
* Revision 1.4 1993/10/19 10:15:22 kaboom
* Now includes tabdat.h.
*
* Revision 1.3 1993/10/08 01:15:59 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.2 1993/09/02 20:10:45 kaboom
* Added macros for flat 24 bitmap routines.
*
* Revision 1.1 1993/04/29 18:35:50 kaboom
* Initial revision
*/
#ifndef __GRCBM_H
#define __GRCBM_H
#include "icanvas.h"
#include "tabdat.h"
/* bitmap draw routines. */
#define gr_clut_ubitmap(bm,x,y,cl) \
((void (*)(grs_bitmap *_bm,short _x,short _y, uchar *_cl)) \
grd_canvas_table[CLUT_DRAW_DEVICE_UBITMAP+2*((bm)->type)])(bm,x,y,cl)
#define gr_clut_bitmap(bm,x,y,cl) \
((int (*)(grs_bitmap *_bm,short _x,short _y, uchar *_cl)) \
grd_canvas_table[CLUT_DRAW_DEVICE_BITMAP+2*((bm)->type)])(bm,x,y,cl)
#define gr_mono_clut_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_MONO_UBITMAP])
#define gr_mono_clut_bitmap \
((int (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_MONO_BITMAP])
#define gr_flat8_clut_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_FLAT8_UBITMAP])
#define gr_flat8_clut_bitmap \
((int (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_FLAT8_BITMAP])
#define gr_flat24_clut_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_FLAT24_UBITMAP])
#define gr_flat24_clut_bitmap \
((int (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_FLAT24_BITMAP])
#define gr_rsd8_clut_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_RSD8_UBITMAP])
#define gr_rsd8_clut_bitmap \
((int (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_RSD8_BITMAP])
#define gr_tluc8_clut_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_TLUC8_UBITMAP])
#define gr_tluc8_clut_bitmap \
((int (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_DRAW_TLUC8_BITMAP])
#endif /* !__GRDBM_H */
@@ -0,0 +1,54 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grclhbm.h $
* $Revision: 1.2 $
* $Author: kaboom $
* $Date: 1993/10/08 01:15:56 $
* Dispatch macros for clut horizontal bitmap flip routines.
*
* This file is part of the 2d library.
*
* $Log: grclhbm.h $
* Revision 1.2 1993/10/08 01:15:56 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.1 1993/10/06 13:50:54 kevin
* Initial revision
*
*/
#ifndef __GRCLHBM_H
#define __GRCLHBM_H
#include "icanvas.h"
#define gr_clut_hflip_ubitmap(bm,x,y,cl) \
((void (*)(grs_bitmap *_bm,short _x,short _y,uchar *_cl)) \
grd_canvas_table[CLUT_HFLIP_DEVICE_UBITMAP+2*((bm)->type)])(bm,x,y,cl)
#define gr_clut_hflip_bitmap(bm,x,y,cl) \
((void (*)(grs_bitmap *_bm,short _x,short _y,uchar *_cl)) \
grd_canvas_table[CLUT_HFLIP_DEVICE_BITMAP+2*((bm)->type)])(bm,x,y,cl)
#define gr_clut_hflip_flat8_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_HFLIP_FLAT8_UBITMAP])
#define gr_clut_hflip_flat8_bitmap \
((void (*)(grs_bitmap *bm,short x,short y,uchar *cl)) \
grd_canvas_table[CLUT_HFLIP_FLAT8_BITMAP])
#endif /* !__GRCLHBM_H */
@@ -0,0 +1,55 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grcply.h $
* $Revision: 1.4 $
* $Author: baf $
* $Date: 1994/02/14 20:38:39 $
*
* Dispatch macros for color shaded polygon routines.
*
* This file is part of the 2d library.
*
* $Log: grcply.h $
* Revision 1.4 1994/02/14 20:38:39 baf
* Added dummy parameter to cpoly and spoly routines, for uniformity needed by 3D.
*
* Revision 1.3 1993/11/29 20:27:39 baf
* General revisions and tidying/up of translucency
* and shading routines
*
* Revision 1.2 1993/11/23 17:52:45 baf
* Added tluc/8 interpolation
*
* Revision 1.1 1993/10/19 10:16:55 kaboom
* Initial revision
*
*/
#ifndef __GRCPLY_H
#define __GRCPLY_H
#include "icanvas.h"
#include "plytyp.h"
#include "tabdat.h"
#define gr_ucpoly \
((void (*)(long c, int n,grs_vertex **vpl))grd_canvas_table[FIX_UCPOLY])
#define gr_cpoly \
((int (*)(long c, int n,grs_vertex **vpl))grd_canvas_table[FIX_CPOLY])
#endif /* !__GRCPLY_H */
+83
View File
@@ -0,0 +1,83 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/grd.c $
* $Revision: 1.10 $
* $Author: kevin $
* $Date: 1994/12/05 21:07:24 $
*
* Global stuff.
*
* This file is part of the 2d library.
*/
#include "grs.h"
/* pointer to the currently set screen. */
grs_screen *grd_screen=NULL;
/* pointer to palette */
uchar grd_default_pal[768];
uchar *grd_pal=grd_default_pal;
/* pointer to blend palette */
grs_rgb grd_default_bpal[1024];
grs_rgb *grd_bpal=grd_default_bpal;
/* pointer to inverse palette */
uchar *grd_ipal=NULL;
/* pointer to a canvas for the current virtual screen. */
grs_canvas *grd_screen_canvas;
/* pointer to a canvas for the visible sub-region of the virtual screen. */
grs_canvas *grd_visible_canvas;
/* pointer to currently set canvas. */
grs_canvas *grd_canvas;
/* info for current graphics setup. */
grs_sys_info grd_info;
grs_drvcap grd_mode_cap;
/* capability info for currently set driver. */
grs_drvcap *grd_cap = &grd_mode_cap;
/* pointer to start of current device driver's function table. */
void (**grd_device_table)();
void (**grd_pixel_table)();
/* pointer to start of current bitmap driver's function table for clipped
primitives. */
void (**grd_canvas_table)();
/* currently active graphics mode. -1 means unrecognized mode */
int grd_mode=-1;
/* flag for whether we are executing in an interrupt. */
uchar grd_interrupt=0;
/* Function chaining globals. Set during gr_set_canvas; that's why I moved them here. */
short grd_pixel_index, grd_canvas_index;
uchar chn_flags;
/* Graphics capability detection function pointer. */
int (*grd_detect_func)(grs_sys_info *info);
+78
View File
@@ -0,0 +1,78 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grd.h $
* $Revision: 1.7 $
* $Author: kaboom $
* $Date: 1993/10/19 10:20:07 $
*
* Declarations for globals.
*
* This file is part of the 2d library.
*
* $Log: grd.h $
* Revision 1.7 1993/10/19 10:20:07 kaboom
* Moved declarations for canvas-related globals to other files.
*
* Revision 1.6 1993/10/08 01:15:58 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.5 1993/10/06 16:13:18 baf
* Added span_texture global
*
* Revision 1.4 1993/09/07 02:21:57 kaboom
* New declaration for grd_mode.
*
* Revision 1.3 1993/05/03 16:47:18 kaboom
* Added declaration for grd_pixel_table.
*
* Revision 1.2 1993/04/29 18:35:34 kaboom
* Moved some of the globals to other files.
*
* Revision 1.1 1993/02/04 17:34:19 kaboom
* Initial revision
*/
#ifndef __GRD_H
#define __GRD_H
#include "grs.h"
extern grs_sys_info grd_info;
extern grs_drvcap *grd_cap;
extern grs_drvcap grd_mode_cap;
extern void (**grd_driver_list[])();
extern int grd_mode;
/* support old-syle dr_ naming for now. */
#define grd_scr_canv grd_screen_canvas
#define grd_vis_canv grd_visible_canvas
#define dr_screen grd_screen
#define dr_canvas grd_canvas
#define dr_scr_canv grd_screen_canvas
#define dr_vis_canv grd_visible_canvas
#define dr_bm grd_bm
#define dr_gc grd_gc
#define dr_ytab grd_ytab
#define dr_int_clip grd_int_clip
#define dr_fix_clip grd_fix_clip
#define dr_clip grd_clip
#define driver_func grd_driver_func
#endif /* !__GRD_H */
+89
View File
@@ -0,0 +1,89 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grdbm.h $
* $Revision: 1.5 $
* $Author: baf $
* $Date: 1993/12/01 21:27:36 $
*
* Dispatch macros for bitmap draw functions.
*
* This file is part of the 2d library.
*
* $Log: grdbm.h $
* Revision 1.5 1993/12/01 21:27:36 baf
* Added macros for translucent/8 bitmaps.
*
* Revision 1.4 1993/10/19 10:15:22 kaboom
* Now includes tabdat.h.
*
* Revision 1.3 1993/10/08 01:15:59 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.2 1993/09/02 20:10:45 kaboom
* Added macros for flat 24 bitmap routines.
*
* Revision 1.1 1993/04/29 18:35:50 kaboom
* Initial revision
*/
#ifndef __GRDBM_H
#define __GRDBM_H
#include "icanvas.h"
#include "tabdat.h"
/* bitmap draw routines. */
#define gr_ubitmap(bm,x,y) \
((void (*)(grs_bitmap *_bm,short _x,short _y)) \
grd_canvas_table[DRAW_DEVICE_UBITMAP+2*((bm)->type)])(bm,x,y)
#define gr_bitmap(bm,x,y) \
((int (*)(grs_bitmap *_bm,short _x,short _y)) \
grd_canvas_table[DRAW_DEVICE_BITMAP+2*((bm)->type)])(bm,x,y)
#define gr_mono_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_MONO_UBITMAP])
#define gr_mono_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_MONO_BITMAP])
#define gr_flat8_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_FLAT8_UBITMAP])
#define gr_flat8_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_FLAT8_BITMAP])
#define gr_flat24_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_FLAT24_UBITMAP])
#define gr_flat24_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_FLAT24_BITMAP])
#define gr_rsd8_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_RSD8_UBITMAP])
#define gr_rsd8_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_RSD8_BITMAP])
#define gr_tluc8_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_TLUC8_UBITMAP])
#define gr_tluc8_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[DRAW_TLUC8_BITMAP])
#endif /* !__GRDBM_H */
+86
View File
@@ -0,0 +1,86 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grdev.h $
* $Revision: 1.5 $
* $Author: kaboom $
* $Date: 1993/10/19 10:15:44 $
*
* Macros for table driven device driver functions.
*
* This file is part of the 2d library.
*
* $Log: grdev.h $
* Revision 1.5 1993/10/19 10:15:44 kaboom
* Now includes tabdat.h. Also put null-check for init and close device
* in here instead of requiring caller to do it.
*
* Revision 1.4 1993/10/08 01:16:00 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.3 1993/05/16 00:35:28 kaboom
* Added arguments to macros for gr_set_state() and gr_get_state().
*
* Revision 1.2 1993/05/04 15:41:30 kaboom
* Changed names of hblank and vblank to htrace and vtrace.
*
* Revision 1.1 1993/04/29 18:36:04 kaboom
* Initial revision
*/
#ifndef __GRDEV_H
#define __GRDEV_H
#include "grs.h"
#include "idevice.h"
#include "tabdat.h"
/* here are the definitions for all the table driven function. */
#define gr_init_device(info) \
(grd_device_table[GRT_INIT_DEVICE] ?\
((int (*)(grs_sys_info *_info))grd_device_table[GRT_INIT_DEVICE])(info) :\
0)
#define gr_close_device(info) \
(grd_device_table[GRT_CLOSE_DEVICE] ?\
((int (*)(grs_sys_info *_info))grd_device_table[GRT_CLOSE_DEVICE])(info) :\
0)
#define gr_set_screen_mode \
((int (*)(int mode,int clear))grd_device_table[GRT_SET_MODE])
#define gr_get_screen_mode \
((int (*)(void))grd_device_table[GRT_GET_MODE])
#define gr_set_state \
((int (*)(void *buf,int clear))grd_device_table[GRT_SET_STATE])
#define gr_get_state \
((int (*)(void *buf,int flags))grd_device_table[GRT_GET_STATE])
#define gr_stat_htrace \
((int (*)(void))grd_device_table[GRT_STAT_HTRACE])
#define gr_stat_vtrace \
((int (*)(void))grd_device_table[GRT_STAT_VTRACE])
#define gr_set_screen_pal \
((void (*)(int start,int n,uchar *pal_data))grd_device_table[GRT_SET_PAL])
#define gr_get_screen_pal \
((void (*)(int start,int n,uchar *pal_data))grd_device_table[GRT_GET_PAL])
#define gr_set_width \
((void (*)(short w))grd_device_table[GRT_SET_WIDTH])
#define gr_get_width \
((short (*)(void))grd_device_table[GRT_GET_WIDTH])
#define gr_set_focus \
((void (*)(short x,short y))grd_device_table[GRT_SET_FOCUS])
#define gr_get_focus \
((void (*)())grd_device_table[GRT_GET_FOCUS])
#endif /* !__GRDEV_H */
+68
View File
@@ -0,0 +1,68 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grgbm.h $
* $Revision: 1.2 $
* $Author: kaboom $
* $Date: 1993/10/08 01:16:01 $
*
* Dispatch macros for get bitmap functions.
*
* This file is part of the 2d library.
*
* $Log: grgbm.h $
* Revision 1.2 1993/10/08 01:16:01 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.1 1993/04/29 18:36:18 kaboom
* Initial revision
*
*/
#ifndef __GRGBM_H
#define __GRGBM_H
#include "icanvas.h"
/* bitmap get routines. */
#define gr_get_ubitmap(bm,x,y) \
((void (*)(grs_bitmap *_bm,short _x,short _y)) \
grd_canvas_table[GET_DEVICE_UBITMAP+2*((bm)->type)])(bm,x,y)
#define gr_get_bitmap(bm,x,y) \
((int (*)(grs_bitmap *_bm,short _x,short _y)) \
grd_canvas_table[GET_DEVICE_BITMAP+2*((bm)->type)])(bm,x,y)
#define gr_get_mono_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[GET_MONO_UBITMAP])
#define gr_get_mono_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[GET_MONO_BITMAP])
#define gr_get_flat8_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[GET_FLAT8_UBITMAP])
#define gr_get_flat8_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[GET_FLAT8_BITMAP])
#define gr_get_rsd8_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[GET_RSD8_UBITMAP]
#define gr_get_rsd8_bitmap \
((int (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[GET_RSD8_BITMAP])
#endif /* !__GRGBM_H */
+61
View File
@@ -0,0 +1,61 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/grhbm.h $
* $Revision: 1.3 $
* $Author: kevin $
* $Date: 1994/11/11 16:48:10 $
*
* Dispatch macros for horizontal bitmap flip routines.
*
* This file is part of the 2d library.
*
* $Log: grhbm.h $
* Revision 1.3 1994/11/11 16:48:10 kevin
* added hflip_in_place primitive.
*
* Revision 1.2 1993/10/08 01:16:02 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.1 1993/06/06 15:13:10 kaboom
* Initial revision
*
*/
#ifndef __GRHBM_H
#define __GRHBM_H
#include "grs.h"
#include "icanvas.h"
extern void gr_hflip_in_place(grs_bitmap *bm);
#define gr_hflip_ubitmap(bm,x,y) \
((void (*)(grs_bitmap *_bm,short _x,short _y)) \
grd_canvas_table[HFLIP_DEVICE_UBITMAP+2*((bm)->type)])(bm,x,y)
#define gr_hflip_bitmap(bm,x,y) \
((void (*)(grs_bitmap *_bm,short _x,short _y)) \
grd_canvas_table[HFLIP_DEVICE_BITMAP+2*((bm)->type)])(bm,x,y)
#define gr_hflip_flat8_ubitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[HFLIP_FLAT8_UBITMAP])
#define gr_hflip_flat8_bitmap \
((void (*)(grs_bitmap *bm,short x,short y)) \
grd_canvas_table[HFLIP_FLAT8_BITMAP])
#endif /* !__GRHBM_H */
@@ -0,0 +1,86 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grilin.c $
* $Revision: 1.4 $
* $Author: lmfeeney $
* $Date: 1994/06/11 02:29:21 $
*
* Integral line drawers. Converts integers to fixed-point and calls
* normal line drawers.
*
* This file is part of the 2d library.
*
* $Log: grilin.c $
* Revision 1.4 1994/06/11 02:29:21 lmfeeney
* provides both interfaces to unclipped line drawer, unclipped
* drawer moved
*
* Revision 1.3 1993/10/08 01:16:03 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.2 1993/04/29 18:49:38 kaboom
* Changed include of old gr.h to new grrend.h.
*
* Revision 1.1 1993/03/29 18:44:53 kaboom
* Initial revision
*/
#include "fix.h"
#include "clpcon.h"
#include "plytyp.h"
#include "lintyp.h"
#include "clpltyp.h"
#include "clpltab.h"
#include "ctxmac.h"
#include "grlin.h"
// prototypes
int gr_int_line (short x0, short y0, short x1, short y1);
int gr_int_line (short x0, short y0, short x1, short y1)
{
int r;
grs_vertex v0, v1;
v0.x = x0; v0.y = y0; /* we don't need no stinking type checking */
v1.x = x1; v1.y = y1;
r = grd_iline_clip_fill (gr_get_fcolor(), gr_get_fill_parm(), &v0, &v1);
return r;
}
int gri_iline_clip_fill (long c, long parm, grs_vertex *v0, grs_vertex *v1)
{
int r;
grs_vertex u0, u1;
u0.x = fix_make(v0->x, 32768); u0.y = fix_make(v0->y, 32768);
u1.x = fix_make(v1->x, 32768); u1.y = fix_make(v1->y, 32768);
r = gri_line_clip (&u0, &u1);
if (r != CLIP_ALL)
grd_uline_fill (c, parm, &u0, &u1);
return r;
}
+56
View File
@@ -0,0 +1,56 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/grlin.h $
* $Revision: 1.2 $
* $Author: kevin $
* $Date: 1994/08/04 09:46:07 $
*/
#ifndef __GRLIN_H
#define __GRLIN_H
#include "plytyp.h"
#include "line.h"
#include "lintyp.h"
#include "clpltyp.h"
#define grd_uline_fill ((grt_uline_fill_v) (grd_uline_fill_vector[GR_LINE]))
#define grd_uiline_fill ((grt_uline_fill_v) (grd_uline_fill_vector[GR_ILINE]))
#define grd_uhline_fill ((grt_uline_fill_xy) (grd_uline_fill_vector[GR_HLINE]))
#define grd_uvline_fill ((grt_uline_fill_xy) (grd_uline_fill_vector[GR_VLINE]))
#define grd_usline_fill ((grt_uline_fill_v) (grd_uline_fill_vector[GR_SLINE]))
#define grd_ucline_fill ((grt_uline_fill_v) (grd_uline_fill_vector[GR_CLINE]))
#define grd_wire_poly_uline_fill ((grt_wire_poly_uline) (grd_uline_fill_vector[GR_WIRE_POLY_LINE]))
#define grd_wire_poly_usline_fill ((grt_wire_poly_usline) (grd_uline_fill_vector[GR_WIRE_POLY_SLINE]))
#define grd_wire_poly_ucline_fill ((grt_wire_poly_ucline) (grd_uline_fill_vector[GR_WIRE_POLY_CLINE]))
/* these should become table definitions */
#define grd_line_clip_fill ((grt_line_clip_fill_v) (grd_line_clip_fill_vector[GR_LINE]))
#define grd_iline_clip_fill ((grt_line_clip_fill_v) (grd_line_clip_fill_vector[GR_ILINE]))
#define grd_hline_clip_fill ((grt_line_clip_fill_xy) (grd_line_clip_fill_vector[GR_HLINE]))
#define grd_vline_clip_fill ((grt_line_clip_fill_xy) (grd_line_clip_fill_vector[GR_VLINE]))
#define grd_sline_clip_fill ((grt_line_clip_fill_v) (grd_line_clip_fill_vector[GR_SLINE]))
#define grd_cline_clip_fill ((grt_line_clip_fill_v) (grd_line_clip_fill_vector[GR_CLINE]))
#define grd_wire_poly_line_clip_fill ((grt_wire_poly_uline) (grd_line_clip_fill_vector[GR_WIRE_POLY_LINE]))
#define grd_wire_poly_sline_clip_fill ((grt_wire_poly_usline) (grd_line_clip_fill_vector[GR_WIRE_POLY_SLINE]))
#define grd_wire_poly_cline_clip_fill ((grt_wire_poly_ucline) (grd_line_clip_fill_vector[GR_WIRE_POLY_CLINE]))
#endif
@@ -0,0 +1,52 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grmalloc.c $
* $Revision: 1.1 $
* $Author: kaboom $
* $Date: 1993/02/04 17:35:34 $
*
* 2d internal memory allocation routines.
*
* This file is part of the 2d library.
*/
#include <stdlib.h>
/* dynamic memory allocation/deallocation is done through the indirected
functions gr_malloc() and gr_free(). they default to malloc() and
free(). library clients can change the default with gr_set_malloc()
and gr_set_free(). */
typedef void *(*ptr_type)(int);
typedef void (*free_type)(void *);
void *(*gr_malloc)(int n) = (ptr_type) malloc;
void (*gr_free)(void *m) = (free_type)free;
/* set 2d's internal function pointer to a malloc routine. */
void gr_set_malloc (void *(*malloc_func)(int bytes))
{
gr_malloc = malloc_func;
}
/* set 2d's internal function pointer to a free routine. */
void gr_set_free (void (*free_func)(void *mem))
{
gr_free = free_func;
}
@@ -0,0 +1,38 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grmalloc.h $
* $Revision: 1.1 $
* $Author: kaboom $
* $Date: 1993/02/04 17:35:18 $
*
* Declarations for 2d internal memory allocation routines.
*
* This file is part of the 2d library.
*/
#ifndef __GRMALLOC_H
#define __GRMALLOC_H
extern void gr_set_malloc (void *(*malloc_func)(int bytes));
extern void gr_set_free (void (*free_func)(void *mem));
extern void *(*gr_malloc)(int n);
extern void (*gr_free)(void *p);
#endif /* !__GRMALLOC_H */
@@ -0,0 +1,41 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grnull.c $
* $Revision: 1.2 $
* $Author: kaboom $
* $Date: 1993/08/20 15:05:22 $
*
* Null-function placeholder.
*
* This file is part of the 2d library.
*
* $Log: grnull.c $
* Revision 1.2 1993/08/20 15:05:22 kaboom
* Took out mprintf.
*
* Revision 1.1 1993/02/04 17:36:07 kaboom
* Initial revision
*/
#include <lg.h>
void gr_null (void) {}
void gr_not_imp (void) {DEBUG("%s: Graphics function not implemented", __FUNCTION__);}
void gr_not_imp_test (void) {}
@@ -0,0 +1,42 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grnull.h $
* $Revision: 1.1 $
* $Author: kaboom $
* $Date: 1993/02/04 17:36:36 $
*
* Null-function placeholder prototype.
*
* This file is part of the 2d library.
*
* $Log: grnull.h $
* Revision 1.1 1993/02/04 17:36:36 kaboom
* Initial revision
*
*/
#ifndef __GRNULL_H
#define __GRNULL_H
extern void gr_null (void);
extern void gr_not_imp (void);
extern void gr_not_imp_test (void);
#endif /* !__GRNULL_H */
+54
View File
@@ -0,0 +1,54 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grp24.h $
* $Revision: 1.3 $
* $Author: kaboom $
* $Date: 1993/10/19 10:18:46 $
*
* Dispatch macros for 24-bit pixel functions.
*
* This file is part of the 2d library.
*
* $Log: grp24.h $
* Revision 1.3 1993/10/19 10:18:46 kaboom
* Now includes tabdat.h.
*
* Revision 1.2 1993/10/08 01:16:05 kaboom
* Changed quotes in #include lines to angle brackets for Watcom.
*
* Revision 1.1 1993/09/02 20:11:35 kaboom
* Initial revision
*/
#ifndef __GRP24_H
#define __GRP24_H
#include "icanvas.h"
#include "tabdat.h"
#define gr_set_upixel24 \
((void (*)(long color,short x,short y))grd_pixel_table[SET_UPIXEL24])
#define gr_set_pixel24 \
((int (*)(long color,short x,short y))grd_pixel_table[SET_PIXEL24])
#define gr_get_upixel24 \
((long (*)(short x,short y))grd_pixel_table[GET_UPIXEL24])
#define gr_get_pixel24 \
((long (*)(short x,short y))grd_pixel_table[GET_PIXEL24])
#endif /* !__GRP24_H */
+78
View File
@@ -0,0 +1,78 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/grpix.h $
* $Revision: 1.7 $
* $Author: kevin $
* $Date: 1994/11/12 02:22:57 $
*
* Dispatch macros for pixel functions.
*
* This file is part of the 2d library.
*
* $Log: grpix.h $
* Revision 1.7 1994/11/12 02:22:57 kevin
* added gr_set_pixel_interrupt() #define.
*
* Revision 1.6 1994/08/16 15:34:57 kevin
* Added gr_fill_upixel declaration.
*
* Revision 1.5 1993/10/19 10:18:47 kaboom
* Now includes tabdat.h.
*
* Revision 1.4 1993/10/08 01:16:06 kaboom
* Changed quotes in #include liness to angle brackets for Watcom problem.
*
* Revision 1.3 1993/09/02 20:11:19 kaboom
* Updated index names to XXX_PIXEL8.
*
* Revision 1.2 1993/05/03 16:50:09 kaboom
* Changed pixel macros to use grd_pixel_table instead of grd_canvas_table.
*
* Revision 1.1 1993/04/29 18:36:36 kaboom
* Initial revision
*/
#ifndef __GRPIX_H
#define __GRPIX_H
#include "icanvas.h"
#include "ifcn.h"
#include "tabdat.h"
#define gr_set_upixel \
((void (*)(long color, short x, short y))grd_pixel_table[SET_UPIXEL8])
#define gr_set_pixel \
((int (*)(long color, short x, short y))grd_pixel_table[SET_PIXEL8])
#define gr_set_upixel_interrupt \
((void (*)(long color, short x, short y))grd_pixel_table[SET_UPIXEL8_INTERRUPT])
#define gr_set_pixel_interrupt \
((int (*)(long color, short x, short y))grd_pixel_table[SET_PIXEL8_INTERRUPT])
extern int gen_fill_pixel(long color, short x, short y);
#define gr_fill_upixel \
((void (*)(long color, short x, short y))grd_function_table[GRC_PIXEL])
#define gr_fill_pixel gen_fill_pixel
#define gr_get_upixel \
((long (*)(short x, short y))grd_pixel_table[GET_UPIXEL8])
#define gr_get_pixel \
((long (*)(short x, short y))grd_pixel_table[GET_PIXEL8])
#endif /* !__GRPIX_H */
+56
View File
@@ -0,0 +1,56 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grply.h $
* $Revision: 1.2 $
* $Author: baf $
* $Date: 1993/11/23 17:52:47 $
*
* Dispatch macros for solid polygon routines.
*
* This file is part of the 2d library.
*
* $Log: grply.h $
* Revision 1.2 1993/11/23 17:52:47 baf
* Added tluc/8 interpolation
*
* Revision 1.1 1993/10/19 10:20:53 kaboom
* Initial revision
*
*/
#ifndef __GRPLY_H
#define __GRPLY_H
#include "icanvas.h"
#include "plytyp.h"
#include "tabdat.h"
#define gr_upoly \
((void (*)(long c,int n,grs_vertex **vpl)) \
grd_canvas_table[FIX_UPOLY])
#define gr_poly \
((int (*)(long c,int n,grs_vertex **vpl)) \
grd_canvas_table[FIX_POLY])
#define gr_tluc8_upoly \
((void (*)(long c,int n,grs_vertex **vpl)) \
grd_canvas_table[FIX_TLUC8_UPOLY])
#define gr_tluc8_poly \
((int (*)(long c,int n,grs_vertex **vpl)) \
grd_canvas_table[FIX_TLUC8_POLY])
#endif /* !__GRPLY_H */
@@ -0,0 +1,91 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grrect.h $
* $Revision: 1.4 $
* $Author: lmfeeney $
* $Date: 1994/06/11 00:36:07 $
*
* Dispatch macros for rectangular/straight functions.
*
* This file is part of the 2d library.
*
* $Log: grrect.h $
* Revision 1.4 1994/06/11 00:36:07 lmfeeney
* lines removed from canvas table, #defines for backward compatibility
*
* Revision 1.3 1993/10/19 10:21:35 kaboom
* Now includes tabdat.h.
*
* Revision 1.2 1993/10/08 01:16:07 kaboom
* Changed quotes in #include lines to angle brackets for Watcom.
*
* Revision 1.1 1993/04/29 18:36:43 kaboom
* Initial revision
*/
#ifndef __GRRECT_H
#define __GRRECT_H
#include "icanvas.h"
#include "tabdat.h"
#include "ctxmac.h"
#include "grlin.h"
#define gr_clear \
((void (*)(long color))grd_canvas_table[DRAW_CLEAR])
#define gr_upoint \
((void (*)(short x,short y))grd_canvas_table[DRAW_UPOINT])
#define gr_point \
((int (*)(short x,short y))grd_canvas_table[DRAW_POINT])
/* The line routines have been removed from the canvas tables */
/* horizontal lines */
#define gr_uhline(x0,y0,x1) \
do {\
grd_uhline_fill ((x0), (y0), (x1), gr_get_fcolor(), gr_get_fill_parm()); \
} while (0)
extern int gen_hline (short x0, short y0, short x1);
#define gr_hline gen_hline
/* vertical lines */
#define gr_uvline(x0,y0,y1) \
do {\
grd_uvline_fill ((x0), (y0), (y1), gr_get_fcolor(), gr_get_fill_parm()); \
} while (0)
extern int gen_vline (short x0, short y0, short y1);
#define gr_vline gen_vline
#define gr_urect \
((void (*)(short x0,short y0,short x1,short y1))grd_canvas_table[DRAW_URECT])
#define gr_rect \
((int (*)(short x0,short y0,short x1,short y1))grd_canvas_table[DRAW_RECT])
#define gr_ubox \
((void (*)(short x0,short y0,short x1,short y1))grd_canvas_table[DRAW_UBOX])
#define gr_box \
((int (*)(short x0,short y0,short x1,short y1))grd_canvas_table[DRAW_BOX])
#endif /* !__GRRECT_H */
+214
View File
@@ -0,0 +1,214 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: r:/prj/lib/src/2d/RCS/grrend.h $
* $Revision: 1.14 $
* $Author: kevin $
* $Date: 1994/08/04 09:46:09 $
*
* Dispatch macros for rendering functions.
*
* This file is part of the 2d library.
*
* $Log: grrend.h $
* Revision 1.14 1994/08/04 09:46:09 kevin
* Added new wire poly line functionality.
*
* Revision 1.13 1994/06/11 00:35:40 lmfeeney
* lines removed from canvas table, #defines for backward compatibility
*
* Revision 1.12 1993/10/26 02:17:43 kevin
* Changed gr_scale... and gr_clut_scale... dispatch macros
* so that they may be used with any bitmap type.
* (rsd8 and flat8 types are currently supported.)
*
* Revision 1.11 1993/10/20 15:22:00 kaboom
* Took out spoly dispatch macros.
*
* Revision 1.10 1993/10/19 10:22:15 kaboom
* Moved solid and color shaded (but not intensity shaded) polygon macros
* to other files.
*
* Revision 1.9 1993/10/02 01:01:41 kaboom
* Moved texture map stuff to other files.
*
* Revision 1.8 1993/09/02 20:12:06 kaboom
* Added macros for dispatching of gr_lin_{u}map by bitmap type. Also
* put in macros for bypass 8- and 24-bit linmaps.
*
* Revision 1.7 1993/08/19 21:51:21 jaemz
* Added bitmap scale clut and voxel functions
*
* Revision 1.6 1993/08/10 19:08:12 kaboom
* Added macros for gr_lit_{u}tmap()
*
* Revision 1.5 1993/07/20 16:24:54 jaemz
* Added interp2 and filterw2
*
* Revision 1.4 1993/06/22 19:59:50 spaz
* Added macros for goroud-shadedl ines:
* gr_fix_usline, sline, ucline, and cline. (fix only)
*
* Revision 1.3 1993/06/14 14:11:33 kaboom
* Added macros for new lin_{u}map and lin_lit_lin_{u}map routines.
*
* Revision 1.2 1993/06/01 13:51:25 kaboom
* Added macros for lit perspective tmappers.
*
* Revision 1.1 1993/04/29 18:36:58 kaboom
* Initial revision
*/
#ifndef __GRREND_H
#define __GRREND_H
#include "grs.h"
#include "icanvas.h"
#include "tabdat.h"
#include "ctxmac.h"
#include "rgb.h"
#include "grlin.h"
/* compatibility -- rah ! */
/* - Lines have been eliminated from the canvas table.
- The preferred interface now takes color and fill parameters and
either a grs_vertex structure or short points.
Unclipped line routines have been inlined to convert parameters and
call the new function via the uline_fill table.
Clipped line routines return a value and so cannot be macro inlined
this way. The canvas lookup macro is now a function which is
extern'ed by it's old 'gen' name.
Again: the preferred interface is through the new parameter'ed functions
in the uline_fill and line_clip_fill tables.
*/
/* lines */
#define gr_fix_line gen_fix_line
extern int gen_fix_line (fix x0, fix y0, fix x1, fix y1);
#define gr_fix_uline(x0,y0,x1,y1)\
do {\
grs_vertex gfu_v0, gfu_v1;\
gfu_v0.x = (x0); gfu_v0.y = (y0);\
gfu_v1.x = (x1); gfu_v1.y = (y1);\
grd_uline_fill(gr_get_fcolor(), \
gr_get_fill_parm(), &gfu_v0, &gfu_v1);\
} while (0)
/* rgb shaded lines */
#define gr_fix_cline gen_fix_cline
extern int gen_fix_cline (fix x0, fix y0, grs_rgb c0, fix x1, fix y1, grs_rgb c1);
#define gr_fix_ucline(x0,y0,c0,x1,y1,c1) \
do { \
grs_vertex gfuc_v0, gfuc_v1; \
\
gfuc_v0.x = (x0); gfuc_v0.y = (y0); \
gfuc_v1.x = (x1); gfuc_v1.y = (y1); \
\
gr_split_rgb ((c0), (uchar*) &(gfuc_v0.u), (uchar*)&(gfuc_v0.v), (uchar*)&(gfuc_v0.w)); \
gr_split_rgb ((c1), (uchar*)&(gfuc_v1.u), (uchar*)&(gfuc_v1.v), (uchar*)&(gfuc_v1.w)); \
\
grd_ucline_fill (gr_get_fcolor(), gr_get_fill_parm(), &gfuc_v0, &gfuc_v1); \
} while(0)
/* i shaded lines */
#define gr_fix_sline gen_fix_sline
extern int gen_fix_sline (fix x0, fix y0, fix i0, fix x1, fix y1, fix i1);
#define gr_fix_usline(x0,y0,i0,x1,y1,i1) \
do { \
grs_vertex gfuc_v0, gfuc_v1; \
\
gfuc_v0.x = (x0); gfuc_v0.y = (y0); gfuc_v0.i = (i0);\
gfuc_v1.x = (x1); gfuc_v1.y = (y1); gfuc_v1.i = (i1);\
\
grd_usline_fill (gr_get_fcolor(), gr_get_fill_parm(), &gfuc_v0, &gfuc_v1); \
} while(0)
/* vertex lines */
#define gr_uline(c,v0,v1) \
grd_uline_fill(c,gr_get_fill_parm(),v0,v1)
#define gr_usline(v0,v1) \
grd_usline_fill(gr_get_fcolor(), gr_get_fill_parm(),v0,v1)
#define gr_ucline(v0,v1) \
grd_ucline_fill(gr_get_fcolor(), gr_get_fill_parm(),v0,v1)
/* wire poly lines */
#define gr_wire_poly_uline(c,v0,v1) \
grd_wire_poly_uline_fill(c, gr_get_fill_parm(),v0,v1)
#define gr_wire_poly_usline(v0,v1) \
grd_wire_poly_usline_fill(gr_get_fcolor(), gr_get_fill_parm(), v0, v1)
#define gr_wire_poly_ucline(v0,v1) \
grd_wire_poly_ucline_fill(gr_get_fcolor(), gr_get_fill_parm(), v0, v1)
#define gr_wire_poly_line(c,v0,v1) \
grd_wire_poly_line_clip_fill(c, gr_get_fill_parm(),v0,v1)
#define gr_wire_poly_sline(v0,v1) \
grd_wire_poly_sline_clip_fill(gr_get_fcolor(), gr_get_fill_parm(), v0, v1)
#define gr_wire_poly_cline(v0,v1) \
grd_wire_poly_cline_clip_fill(gr_get_fcolor(), gr_get_fill_parm(), v0, v1)
/* these continue to do traditional lookup's */
#define gr_vox_rect \
((void (*)(fix x[4],fix y[4],fix dz[3],int near_ver,grs_bitmap *col,grs_bitmap *ht,int dotw,int doth)) \
grd_canvas_table[VOX_RECT])
#define gr_vox_poly \
((void (*)(fix x[4],fix y[4],fix dz[3],int near_ver,grs_bitmap *col,grs_bitmap *ht)) \
grd_canvas_table[VOX_POLY])
#define gr_vox_cpoly \
((void (*)(fix x[4],fix y[4],fix dz[3],int near_ver,grs_bitmap *col,grs_bitmap *ht)) \
grd_canvas_table[VOX_CPOLY])
#define gr_interp2_ubitmap \
((void (*)(grs_bitmap *bm)) grd_canvas_table[INTERP2_UBITMAP])
#define gr_filter2_ubitmap \
((void (*)(grs_bitmap *bm)) grd_canvas_table[FILTER2_UBITMAP])
/* These are horrific: something should be done. */
#define gr_scale_ubitmap(bm,x,y,w,h) \
((void (*)(grs_bitmap *_bm,short _x,short _y,short _w,short _h)) \
grd_canvas_table[SCALE_DEVICE_UBITMAP+2*((bm)->type)]) (bm,x,y,w,h)
#define gr_scale_bitmap(bm,x,y,w,h) \
((int (*)(grs_bitmap *_bm,short _x,short _y,short _w,short _h)) \
grd_canvas_table[SCALE_DEVICE_BITMAP+2*((bm)->type)]) (bm,x,y,w,h)
#define gr_clut_scale_ubitmap(bm,x,y,w,h,cl) \
((int (*)(grs_bitmap *_bm,short _x,short _y,short _w,short _h,uchar *_cl)) \
grd_canvas_table[CLUT_SCALE_DEVICE_UBITMAP+2*((bm)->type)]) \
(bm,x,y,w,h,cl)
#define gr_clut_scale_bitmap(bm,x,y,w,h,cl) \
((int (*)(grs_bitmap *_bm,short _x,short _y,short _w,short _h,uchar *_cl)) \
grd_canvas_table[CLUT_SCALE_DEVICE_BITMAP+2*((bm)->type)]) \
(bm,x,y,w,h,cl)
#define gr_roll_ubitmap grd_canvas_table[ROLL_UBITMAP])
#define gr_roll_bitmap ((int (*)())grd_canvas_table[ROLL_BITMAP])
#endif /* !__GRREND_H */
+248
View File
@@ -0,0 +1,248 @@
/*
Copyright (C) 2015-2018 Night Dive Studios, LLC.
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/>.
*/
/*
* $Source: n:/project/lib/src/2d/RCS/grs.h $
* $Revision: 1.13 $
* $Author: baf $
* $Date: 1993/12/16 00:30:50 $
*
* Public 2D system data structures.
*
* This file is part of the 2d library.
*
* $Log: grs.h $
* Revision 1.13 1993/12/16 00:30:50 baf
* Removed include of spntyp.h
*
* Revision 1.12 1993/12/14 22:36:29 kevin
* Took out perspective mapper context structure. Sorry
* it should never have been
* here in the first place.
*
* Revision 1.11 1993/12/04 12:42:30 kevin
* Added context structure for perspective mappers.
*
* Revision 1.10 1993/10/19 10:22:49 kaboom
* Font member of grs_context is now a grs_font *.
*
* Revision 1.9 1993/10/15 18:04:45 baf
* Moved transtab to screen
*
* Revision 1.8 1993/10/15 12:28:16 baf
* Added transluceny table to graphics context
*
* Revision 1.7 1993/10/06 16:08:56 baf
* Moved grs_span definition to spntyp.h
*
* Revision 1.6 1993/10/06 13:33:57 kevin
* Added default color lookup table to screen type.
*
* Revision 1.5 1993/07/08 23:02:53 kaboom
* Added wlog and hlog fields to grs_bitmap structure.
*
* Revision 1.4 1993/06/01 13:51:46 kaboom
* Added lighting table to screen structure.
*
* Revision 1.3 1993/04/29 18:37:08 kaboom
* Added system info structures. Pared down driver capability structure.
*
* Revision 1.1 1993/02/04 17:36:18 kaboom
* Initial revision
*
********************************************************************
* Log entries from old 2d.h
* Revision 1.20 1993/01/25 11:09:57 matt
* Removed structure definition for 'vector' (leaving in 'grs_vector'),
* since vector conflicted with the 3d structure of the same name.
*
* Revision 1.19 1993/01/22 19:49:02 kaboom
* Added some structures for texture mapper vertices and palette.
*
* Revision 1.18 1993/01/15 21:41:52 kaboom
* Changed grs_stencil to grs_sten_elem and made new grs_stencil that
* includes a flags word.
*
* Revision 1.12 1992/12/30 14:59:53 kaboom
* Changed from using grs_span for stencil elements to new grs_stencil
* type.
*
* Revision 1.8 1992/12/10 11:11:31 kaboom
* Moved ytab field from bitmap structure to canvas. Changed clipping
* regions from 2 structures, which are used as casts, to a union with
* fixed and int fields.
*
* Revision 1.6 1992/11/12 13:54:09 kaboom
* Added type, align and ytab fields to bitmap structure. Reduced
* bitmap flags to a short. Changed clipping region to store fixed-
* point values, and added different structures to allow their access
* as fixed-point or integer values without shifting.
*
* Revision 1.5 1992/10/21 15:58:48 kaboom
* Changed naming for gr_xxx structures to grs_xxx to avoid some name
* collisions with functions.
*
* Revision 1.3 1992/10/09 16:50:55 kaboom
* Added gr_ylrpp structure for scanline pixel-based drawing.
*/
#ifndef __GRS_H
#define __GRS_H
#include "fix.h"
// FIXME pragma pack
#pragma pack(push,2)
/* system information structure. */
typedef struct {
uchar id_maj; /* major id---type of graphics system */
uchar id_min; /* minor id---vendor */
short memory; /* memory in kilobytes */
short modes[16]; /* array of modes, ends with -1 */
} grs_sys_info;
/* mode information descriptor structure. */
typedef struct {
short w; /* screen width */
short h; /* screen height */
uchar b; /* number of bits per pixel */
} grs_mode_info;
/* amazing rgb type. */
typedef uint32_t grs_rgb;
/* structure for bitmaps to be drawn from and to. if a bitmap is contained
within a larger bitmap, the row field tells how wide the containing bitmap
is. */
typedef struct {
uchar *bits; /* ptr to data */
uchar type; /* type of data in bitmap, 1-bit, 8-bit, etc */
uchar align; /* where data really starts */
ushort flags; /* whether compressed, transparent, etc */
short w; /* width in pixels */
short h; /* height */
ushort row; /* bytes in row of containing bitmap */
uchar wlog; /* log2 of w */
uchar hlog; /* log2 of h */
} grs_bitmap;
/* stencil element for non-rectangular clipping. */
typedef struct _sten {
short l; /* left edge of stencil */
short r; /* right */
struct _sten *n; /* pointer to next span in this scanline */
} grs_sten_elem;
/* stencil header for non-rectangular clipping. */
typedef struct {
grs_sten_elem *elem; /* pointer to first stencil element */
int32_t flags; /* specific stencil data. */
} grs_stencil;
/* structure for clipping regions. a clipping region can either be a simple
rectangle (given by left,top,right,bot) or a grs_stencil, pointed to by
sten. */
typedef union {
struct {
grs_stencil *sten; /* pointer to stencil for nonrect clip region */
fix left; /* current clipping rectangle */
fix top; /* fixed-point coordinates */
fix right;
fix bot;
} f;
struct {
grs_stencil *sten; /* pointer to stencil for nonrect clip region */
short pad0;
short left; /* current clipping rectangle */
short pad1;
short top; /* integral coordinates */
short pad2;
short right;
short pad3;
short bot;
} i;
} grs_clip;
// Font.
typedef struct {
ushort id;
char dummy1[34];
short min;
short max;
char dummy2[32];
int32_t cotptr;
int32_t buf;
short w;
short h;
short off_tab[1];
} grs_font;
// Access to fonts in resources.
#define FORMAT_FONT FORMAT_RAW
/* structure for drawing context. the context contains data about which
color, font attributes, filling attributes, and an embedded clipping
region structure. */
typedef struct {
int32_t fcolor; /* current drawing color */
int32_t bcolor; /* background color */
grs_font *font; /* font id */
int32_t text_attr; /* attributes for text */
int32_t fill_type; /* how to fill primitives */
intptr_t fill_parm; /* parameter for fill */
grs_clip clip; /* clipping region */
} grs_context;
/* a canvas is a bitmap drawing context. */
typedef struct {
grs_bitmap bm; /* bitmap to draw into/read out of */
grs_context gc; /* graphic context */
uchar **ytab; /* pointer to an optional y table */
} grs_canvas;
/* a screen is a descriptor for a visible region of video memory. */
typedef struct {
grs_bitmap bm; /* where we actually draw */
grs_canvas *c; /* pointer to 2 system canvases */
uchar *pal;
grs_rgb *bpal;
uchar *ipal;
uchar *ltab;
uchar ***transtab;/* table of colors under translucency */
uchar *clut; /* default color lookup table */
short x; /* upper left coordinates of visible */
short y; /* region of virtual buffer */
} grs_screen;
/* driver capability/info structure. */
typedef struct {
fix aspect; /* fixed point aspect ratio w/h */
short w; /* screen width */
short h; /* screen height */
intptr_t *vbase; /* base video address */
} grs_drvcap;
/* 3d point structure for perspective mapper. */
typedef struct {
fix x,y,z; /* 3's */
} grs_point3d;
#pragma pack(pop)
#endif /* !__GRS_H */

Some files were not shown because too many files have changed in this diff Show More