split some code into separate files
new .h files: hacklib.h selvar.h stairs.h
new .c files: calendar.c, getpos.c, report.c, selvar.c, stairs.c,
strutil.c, wizcmds.c
cleanup of hacklib.c and mdlib.c
hacklib contains functions that do not have to link with the core
relocate wiz commands from cmd.c to wizcmds.c
relocate CRASHREPORT stuff to report.c
relocate getpos stuff from do_name.c to getpos.c
remove temporary struct definition from extern.h
cross-compile PRE-section split into cross-pre1.370 and cross-pre2.370
Windows sys/windows/Makefile.nmake and sys/windows/Makefile.mingw32 and
visual studio project file updates
Unix sys/unix/Makefile.src, sys/unix/Makefile.utl
populate selvar.c and selvar.h
build on MS-DOS (not cross-compile) Makefile updates
for sys/msdos/Makefile.GCC (untested)
vms updates for above (untested)
This commit is contained in:
+2
-753
@@ -14,11 +14,8 @@
|
||||
#include "hack.h"
|
||||
#include "sp_lev.h"
|
||||
|
||||
typedef void (*select_iter_func)(coordxy, coordxy, genericptr);
|
||||
|
||||
extern void mkmap(lev_init *);
|
||||
|
||||
static boolean match_maptyps(xint16, xint16);
|
||||
static void solidify_map(void);
|
||||
static void map_cleanup(void);
|
||||
static void lvlfill_maze_grid(int, int, int, int, schar);
|
||||
@@ -101,8 +98,6 @@ static void sel_set_lit(coordxy, coordxy, genericptr_t);
|
||||
static void add_doors_to_room(struct mkroom *);
|
||||
static void get_table_coords_or_region(lua_State *,
|
||||
coordxy *, coordxy *, coordxy *, coordxy *);
|
||||
static void selection_iterate(struct selectionvar *, select_iter_func,
|
||||
genericptr_t);
|
||||
static void sel_set_ter(coordxy, coordxy, genericptr_t);
|
||||
static void sel_set_door(coordxy, coordxy, genericptr_t);
|
||||
static void sel_set_feature(coordxy, coordxy, genericptr_t);
|
||||
@@ -111,11 +106,8 @@ static void get_table_xy_or_coord(lua_State *, lua_Integer *, lua_Integer *);
|
||||
static int get_table_region(lua_State *, const char *, lua_Integer *,
|
||||
lua_Integer *, lua_Integer *, lua_Integer *, boolean);
|
||||
static void set_wallprop_in_selection(lua_State *, int);
|
||||
static coordxy random_wdir(void);
|
||||
static int floodfillchk_match_under(coordxy, coordxy);
|
||||
static int floodfillchk_match_accessible(coordxy, coordxy);
|
||||
static boolean sel_flood_havepoint(coordxy, coordxy, coordxy *, coordxy *, int);
|
||||
static long line_dist_coord(long, long, long, long, long, long);
|
||||
static void l_push_mkroom_table(lua_State *, struct mkroom *);
|
||||
static int get_table_align(lua_State *);
|
||||
static int get_table_monclass(lua_State *);
|
||||
@@ -221,7 +213,7 @@ reset_xystart_size(void)
|
||||
|
||||
/* Does typ match with levl[][].typ, considering special types
|
||||
MATCH_WALL and MAX_TYPE (aka transparency)? */
|
||||
static boolean
|
||||
boolean
|
||||
match_maptyps(xint16 typ, xint16 levltyp)
|
||||
{
|
||||
if ((typ == MATCH_WALL) && !IS_STWALL(levltyp))
|
||||
@@ -4484,371 +4476,16 @@ lspo_random_corridors(lua_State *L UNUSED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* selection */
|
||||
struct selectionvar *
|
||||
selection_new(void)
|
||||
{
|
||||
struct selectionvar *tmps = (struct selectionvar *) alloc(sizeof *tmps);
|
||||
|
||||
tmps->wid = COLNO;
|
||||
tmps->hei = ROWNO;
|
||||
tmps->bounds_dirty = FALSE;
|
||||
tmps->bounds.lx = COLNO;
|
||||
tmps->bounds.ly = ROWNO;
|
||||
tmps->bounds.hx = tmps->bounds.hy = 0;
|
||||
tmps->map = (char *) alloc((COLNO * ROWNO) + 1);
|
||||
(void) memset(tmps->map, 1, (COLNO * ROWNO));
|
||||
tmps->map[(COLNO * ROWNO)] = '\0';
|
||||
|
||||
return tmps;
|
||||
}
|
||||
|
||||
void
|
||||
selection_free(struct selectionvar *sel, boolean freesel)
|
||||
{
|
||||
if (sel) {
|
||||
Free(sel->map);
|
||||
sel->map = NULL;
|
||||
if (freesel)
|
||||
free((genericptr_t) sel);
|
||||
else
|
||||
(void) memset((genericptr_t) sel, 0, sizeof *sel);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear selection, setting all locations to value val */
|
||||
void
|
||||
selection_clear(struct selectionvar *sel, int val)
|
||||
{
|
||||
(void) memset(sel->map, 1 + val, (COLNO * ROWNO));
|
||||
if (val) {
|
||||
sel->bounds.lx = 0;
|
||||
sel->bounds.ly = 0;
|
||||
sel->bounds.hx = COLNO - 1;
|
||||
sel->bounds.hy = ROWNO - 1;
|
||||
} else {
|
||||
sel->bounds.lx = COLNO;
|
||||
sel->bounds.ly = ROWNO;
|
||||
sel->bounds.hx = sel->bounds.hy = 0;
|
||||
}
|
||||
sel->bounds_dirty = FALSE;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_clone(struct selectionvar *sel)
|
||||
{
|
||||
struct selectionvar *tmps = (struct selectionvar *) alloc(sizeof *tmps);
|
||||
|
||||
*tmps = *sel;
|
||||
tmps->map = dupstr(sel->map);
|
||||
|
||||
return tmps;
|
||||
}
|
||||
|
||||
/* get boundary rect of selection sel into b */
|
||||
void
|
||||
selection_getbounds(struct selectionvar *sel, NhRect *b)
|
||||
{
|
||||
if (!sel || !b)
|
||||
return;
|
||||
|
||||
selection_recalc_bounds(sel);
|
||||
|
||||
if (sel->bounds.lx >= sel->wid) {
|
||||
b->lx = 0;
|
||||
b->ly = 0;
|
||||
b->hx = COLNO - 1;
|
||||
b->hy = ROWNO - 1;
|
||||
} else {
|
||||
b->lx = sel->bounds.lx;
|
||||
b->ly = sel->bounds.ly;
|
||||
b->hx = sel->bounds.hx;
|
||||
b->hy = sel->bounds.hy;
|
||||
}
|
||||
}
|
||||
|
||||
/* recalc the boundary of selection, if necessary */
|
||||
void
|
||||
selection_recalc_bounds(struct selectionvar *sel)
|
||||
{
|
||||
coordxy x, y;
|
||||
NhRect r;
|
||||
|
||||
if (!sel->bounds_dirty)
|
||||
return;
|
||||
|
||||
sel->bounds.lx = COLNO;
|
||||
sel->bounds.ly = ROWNO;
|
||||
sel->bounds.hx = sel->bounds.hy = 0;
|
||||
|
||||
r.lx = r.ly = r.hx = r.hy = -1;
|
||||
|
||||
/* left */
|
||||
for (x = 0; x < sel->wid; x++) {
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.lx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.lx > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (r.lx > -1) {
|
||||
/* right */
|
||||
for (x = sel->wid-1; x >= r.lx; x--) {
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.hx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.hx > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
/* top */
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
for (x = r.lx; x <= r.hx; x++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.ly = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.ly > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
/* bottom */
|
||||
for (y = sel->hei-1; y >= r.ly; y--) {
|
||||
for (x = r.lx; x <= r.hx; x++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.hy = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.hy > -1)
|
||||
break;
|
||||
}
|
||||
sel->bounds = r;
|
||||
}
|
||||
|
||||
sel->bounds_dirty = FALSE;
|
||||
}
|
||||
|
||||
coordxy
|
||||
selection_getpoint(
|
||||
coordxy x, coordxy y,
|
||||
struct selectionvar *sel)
|
||||
{
|
||||
if (!sel || !sel->map)
|
||||
return 0;
|
||||
if (x < 0 || y < 0 || x >= sel->wid || y >= sel->hei)
|
||||
return 0;
|
||||
|
||||
return (sel->map[sel->wid * y + x] - 1);
|
||||
}
|
||||
|
||||
void
|
||||
selection_setpoint(
|
||||
coordxy x, coordxy y,
|
||||
struct selectionvar *sel,
|
||||
int c)
|
||||
{
|
||||
if (!sel || !sel->map)
|
||||
return;
|
||||
if (x < 0 || y < 0 || x >= sel->wid || y >= sel->hei)
|
||||
return;
|
||||
|
||||
if (c && !sel->bounds_dirty) {
|
||||
if (sel->bounds.lx > x) sel->bounds.lx = x;
|
||||
if (sel->bounds.ly > y) sel->bounds.ly = y;
|
||||
if (sel->bounds.hx < x) sel->bounds.hx = x;
|
||||
if (sel->bounds.hy < y) sel->bounds.hy = y;
|
||||
} else {
|
||||
sel->bounds_dirty = TRUE;
|
||||
}
|
||||
|
||||
sel->map[sel->wid * y + x] = (char) (c + 1);
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_not(struct selectionvar *s)
|
||||
{
|
||||
int x, y;
|
||||
NhRect tmprect = cg.zeroNhRect;
|
||||
|
||||
for (x = 0; x < s->wid; x++)
|
||||
for (y = 0; y < s->hei; y++)
|
||||
selection_setpoint(x, y, s, selection_getpoint(x, y, s) ? 0 : 1);
|
||||
selection_getbounds(s, &tmprect);
|
||||
return s;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_filter_mapchar(struct selectionvar *ov, xint16 typ, int lit)
|
||||
{
|
||||
int x, y;
|
||||
struct selectionvar *ret;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return NULL;
|
||||
|
||||
ret = selection_new();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, ov)
|
||||
&& match_maptyps(typ, levl[x][y].typ)) {
|
||||
switch (lit) {
|
||||
default:
|
||||
case -2:
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
break;
|
||||
case -1:
|
||||
selection_setpoint(x, y, ret, rn2(2));
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
if (levl[x][y].lit == (unsigned int) lit)
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_filter_percent(
|
||||
struct selectionvar *ov,
|
||||
int percent)
|
||||
{
|
||||
int x, y;
|
||||
struct selectionvar *ret;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return NULL;
|
||||
|
||||
ret = selection_new();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, ov) && (rn2(100) < percent))
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
selection_rndcoord(
|
||||
struct selectionvar *ov,
|
||||
coordxy *x, coordxy *y,
|
||||
boolean removeit)
|
||||
{
|
||||
int idx = 0;
|
||||
int c;
|
||||
int dx, dy;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (dx = rect.lx; dx <= rect.hx; dx++)
|
||||
for (dy = rect.ly; dy <= rect.hy; dy++)
|
||||
if (selection_getpoint(dx, dy, ov))
|
||||
idx++;
|
||||
|
||||
if (idx) {
|
||||
c = rn2(idx);
|
||||
for (dx = rect.lx; dx <= rect.hx; dx++)
|
||||
for (dy = rect.ly; dy <= rect.hy; dy++)
|
||||
if (selection_getpoint(dx, dy, ov)) {
|
||||
if (!c) {
|
||||
*x = dx;
|
||||
*y = dy;
|
||||
if (removeit)
|
||||
selection_setpoint(dx, dy, ov, 0);
|
||||
return 1;
|
||||
}
|
||||
c--;
|
||||
}
|
||||
}
|
||||
*x = *y = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Choose a single random W_* direction. */
|
||||
static coordxy
|
||||
coordxy
|
||||
random_wdir(void)
|
||||
{
|
||||
static const coordxy wdirs[4] = { W_NORTH, W_SOUTH, W_EAST, W_WEST };
|
||||
return wdirs[rn2(4)];
|
||||
}
|
||||
|
||||
void
|
||||
selection_do_grow(struct selectionvar *ov, int dir)
|
||||
{
|
||||
coordxy x, y;
|
||||
struct selectionvar *tmp;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
tmp = selection_new();
|
||||
|
||||
if (dir == W_RANDOM)
|
||||
dir = random_wdir();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = max(0, rect.lx-1); x <= min(COLNO-1, rect.hx+1); x++)
|
||||
for (y = max(0, rect.ly-1); y <= min(ROWNO-1, rect.hy+1); y++) {
|
||||
/* note: dir is a mask of multiple directions, but the only
|
||||
way to specify diagonals is by including the two adjacent
|
||||
orthogonal directions, which effectively specifies three-
|
||||
way growth [WEST|NORTH => WEST plus WEST|NORTH plus NORTH] */
|
||||
if (((dir & W_WEST) && selection_getpoint(x + 1, y, ov))
|
||||
|| (((dir & (W_WEST | W_NORTH)) == (W_WEST | W_NORTH))
|
||||
&& selection_getpoint(x + 1, y + 1, ov))
|
||||
|| ((dir & W_NORTH) && selection_getpoint(x, y + 1, ov))
|
||||
|| (((dir & (W_NORTH | W_EAST)) == (W_NORTH | W_EAST))
|
||||
&& selection_getpoint(x - 1, y + 1, ov))
|
||||
|| ((dir & W_EAST) && selection_getpoint(x - 1, y, ov))
|
||||
|| (((dir & (W_EAST | W_SOUTH)) == (W_EAST | W_SOUTH))
|
||||
&& selection_getpoint(x - 1, y - 1, ov))
|
||||
|| ((dir & W_SOUTH) && selection_getpoint(x, y - 1, ov))
|
||||
|| (((dir & (W_SOUTH | W_WEST)) == (W_SOUTH | W_WEST))
|
||||
&& selection_getpoint(x + 1, y - 1, ov))) {
|
||||
selection_setpoint(x, y, tmp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
selection_getbounds(tmp, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, tmp))
|
||||
selection_setpoint(x, y, ov, 1);
|
||||
|
||||
selection_free(tmp, TRUE);
|
||||
}
|
||||
|
||||
static int (*selection_flood_check_func)(coordxy, coordxy);
|
||||
static schar floodfillchk_match_under_typ;
|
||||
|
||||
void
|
||||
set_selection_floodfillchk(int (*f)(coordxy, coordxy))
|
||||
{
|
||||
selection_flood_check_func = f;
|
||||
}
|
||||
|
||||
static int
|
||||
floodfillchk_match_under(coordxy x, coordxy y)
|
||||
{
|
||||
@@ -4870,373 +4507,6 @@ floodfillchk_match_accessible(coordxy x, coordxy y)
|
||||
|| levl[x][y].typ == SCORR);
|
||||
}
|
||||
|
||||
/* check whethere <x,y> is already in xs[],ys[] */
|
||||
static boolean
|
||||
sel_flood_havepoint(
|
||||
coordxy x, coordxy y,
|
||||
coordxy xs[], coordxy ys[],
|
||||
int n)
|
||||
{
|
||||
coordxy xx = x, yy = y;
|
||||
|
||||
while (n > 0) {
|
||||
--n;
|
||||
if (xs[n] == xx && ys[n] == yy)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
selection_floodfill(
|
||||
struct selectionvar *ov,
|
||||
coordxy x, coordxy y,
|
||||
boolean diagonals)
|
||||
{
|
||||
struct selectionvar *tmp = selection_new();
|
||||
#define SEL_FLOOD_STACK (COLNO * ROWNO)
|
||||
#define SEL_FLOOD(nx, ny) \
|
||||
do { \
|
||||
if (idx < SEL_FLOOD_STACK) { \
|
||||
dx[idx] = (nx); \
|
||||
dy[idx] = (ny); \
|
||||
idx++; \
|
||||
} else \
|
||||
panic(floodfill_stack_overrun); \
|
||||
} while (0)
|
||||
#define SEL_FLOOD_CHKDIR(mx, my, sel) \
|
||||
do { \
|
||||
if (isok((mx), (my)) \
|
||||
&& (*selection_flood_check_func)((mx), (my)) \
|
||||
&& !selection_getpoint((mx), (my), (sel)) \
|
||||
&& !sel_flood_havepoint((mx), (my), dx, dy, idx)) \
|
||||
SEL_FLOOD((mx), (my)); \
|
||||
} while (0)
|
||||
static const char floodfill_stack_overrun[] = "floodfill stack overrun";
|
||||
int idx = 0;
|
||||
coordxy dx[SEL_FLOOD_STACK];
|
||||
coordxy dy[SEL_FLOOD_STACK];
|
||||
|
||||
if (selection_flood_check_func == (int (*)(coordxy, coordxy)) 0) {
|
||||
selection_free(tmp, TRUE);
|
||||
return;
|
||||
}
|
||||
SEL_FLOOD(x, y);
|
||||
do {
|
||||
idx--;
|
||||
x = dx[idx];
|
||||
y = dy[idx];
|
||||
if (isok(x, y)) {
|
||||
selection_setpoint(x, y, ov, 1);
|
||||
selection_setpoint(x, y, tmp, 1);
|
||||
}
|
||||
SEL_FLOOD_CHKDIR((x + 1), y, tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), y, tmp);
|
||||
SEL_FLOOD_CHKDIR(x, (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR(x, (y - 1), tmp);
|
||||
if (diagonals) {
|
||||
SEL_FLOOD_CHKDIR((x + 1), (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), (y - 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x + 1), (y - 1), tmp);
|
||||
}
|
||||
} while (idx > 0);
|
||||
#undef SEL_FLOOD
|
||||
#undef SEL_FLOOD_STACK
|
||||
#undef SEL_FLOOD_CHKDIR
|
||||
selection_free(tmp, TRUE);
|
||||
}
|
||||
|
||||
/* McIlroy's Ellipse Algorithm */
|
||||
void
|
||||
selection_do_ellipse(
|
||||
struct selectionvar *ov,
|
||||
int xc, int yc,
|
||||
int a, int b,
|
||||
int filled)
|
||||
{ /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
|
||||
int x = 0, y = b;
|
||||
long a2 = (long) a * a, b2 = (long) b * b;
|
||||
long crit1 = -(a2 / 4 + a % 2 + b2);
|
||||
long crit2 = -(b2 / 4 + b % 2 + a2);
|
||||
long crit3 = -(b2 / 4 + b % 2);
|
||||
long t = -a2 * y; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */
|
||||
long dxt = 2 * b2 * x, dyt = -2 * a2 * y;
|
||||
long d2xt = 2 * b2, d2yt = 2 * a2;
|
||||
long width = 1;
|
||||
long i;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
filled = !filled;
|
||||
|
||||
if (!filled) {
|
||||
while (y >= 0 && x <= a) {
|
||||
selection_setpoint(xc + x, yc + y, ov, 1);
|
||||
if (x != 0 || y != 0)
|
||||
selection_setpoint(xc - x, yc - y, ov, 1);
|
||||
if (x != 0 && y != 0) {
|
||||
selection_setpoint(xc + x, yc - y, ov, 1);
|
||||
selection_setpoint(xc - x, yc + y, ov, 1);
|
||||
}
|
||||
if (t + b2 * x <= crit1 /* e(x+1,y-1/2) <= 0 */
|
||||
|| t + a2 * y <= crit3) { /* e(x+1/2,y) <= 0 */
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
} else if (t - a2 * y > crit2) { /* e(x+1/2,y-1) > 0 */
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
} else {
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (y >= 0 && x <= a) {
|
||||
if (t + b2 * x <= crit1 /* e(x+1,y-1/2) <= 0 */
|
||||
|| t + a2 * y <= crit3) { /* e(x+1/2,y) <= 0 */
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
width += 2;
|
||||
} else if (t - a2 * y > crit2) { /* e(x+1/2,y-1) > 0 */
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc - y, ov, 1);
|
||||
if (y != 0)
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc + y, ov, 1);
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
} else {
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc - y, ov, 1);
|
||||
if (y != 0)
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc + y, ov, 1);
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
width += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* square of distance from line segment (x1,y1, x2,y2) to point (x3,y3) */
|
||||
static long
|
||||
line_dist_coord(long x1, long y1, long x2, long y2, long x3, long y3)
|
||||
{
|
||||
long px = x2 - x1;
|
||||
long py = y2 - y1;
|
||||
long s = px * px + py * py;
|
||||
long x, y, dx, dy, distsq = 0;
|
||||
float lu = 0;
|
||||
|
||||
if (x1 == x2 && y1 == y2)
|
||||
return dist2(x1, y1, x3, y3);
|
||||
|
||||
lu = ((x3 - x1) * px + (y3 - y1) * py) / (float) s;
|
||||
if (lu > 1)
|
||||
lu = 1;
|
||||
else if (lu < 0)
|
||||
lu = 0;
|
||||
|
||||
x = x1 + lu * px;
|
||||
y = y1 + lu * py;
|
||||
dx = x - x3;
|
||||
dy = y - y3;
|
||||
distsq = dx * dx + dy * dy;
|
||||
|
||||
return distsq;
|
||||
}
|
||||
|
||||
/* guts of l_selection_gradient */
|
||||
void
|
||||
selection_do_gradient(
|
||||
struct selectionvar *ov,
|
||||
long x, long y,
|
||||
long x2,long y2,
|
||||
long gtyp,
|
||||
long mind, long maxd)
|
||||
{
|
||||
long dx, dy, dofs;
|
||||
|
||||
if (mind > maxd) {
|
||||
long tmp = mind;
|
||||
mind = maxd;
|
||||
maxd = tmp;
|
||||
}
|
||||
|
||||
dofs = maxd * maxd - mind * mind;
|
||||
if (dofs < 1)
|
||||
dofs = 1;
|
||||
|
||||
switch (gtyp) {
|
||||
default:
|
||||
impossible("Unrecognized gradient type! Defaulting to radial...");
|
||||
/* FALLTHRU */
|
||||
case SEL_GRADIENT_RADIAL: {
|
||||
for (dx = 0; dx < COLNO; dx++)
|
||||
for (dy = 0; dy < ROWNO; dy++) {
|
||||
long d0 = line_dist_coord(x, y, x2, y2, dx, dy);
|
||||
|
||||
if (d0 <= mind * mind
|
||||
|| (d0 <= maxd * maxd && d0 - mind * mind < rn2(dofs)))
|
||||
selection_setpoint(dx, dy, ov, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SEL_GRADIENT_SQUARE: {
|
||||
for (dx = 0; dx < COLNO; dx++)
|
||||
for (dy = 0; dy < ROWNO; dy++) {
|
||||
long d1 = line_dist_coord(x, y, x2, y2, x, dy);
|
||||
long d2 = line_dist_coord(x, y, x2, y2, dx, y);
|
||||
long d3 = line_dist_coord(x, y, x2, y2, x2, dy);
|
||||
long d4 = line_dist_coord(x, y, x2, y2, dx, y2);
|
||||
long d5 = line_dist_coord(x, y, x2, y2, dx, dy);
|
||||
long d0 = min(d5, min(max(d1, d2), max(d3, d4)));
|
||||
|
||||
if (d0 <= mind * mind
|
||||
|| (d0 <= maxd * maxd && d0 - mind * mind < rn2(dofs)))
|
||||
selection_setpoint(dx, dy, ov, 1);
|
||||
}
|
||||
break;
|
||||
} /*case*/
|
||||
} /*switch*/
|
||||
}
|
||||
|
||||
/* bresenham line algo */
|
||||
void
|
||||
selection_do_line(
|
||||
coordxy x1, coordxy y1,
|
||||
coordxy x2, coordxy y2,
|
||||
struct selectionvar *ov)
|
||||
{
|
||||
int d0, dx, dy, ai, bi, xi, yi;
|
||||
|
||||
if (x1 < x2) {
|
||||
xi = 1;
|
||||
dx = x2 - x1;
|
||||
} else {
|
||||
xi = -1;
|
||||
dx = x1 - x2;
|
||||
}
|
||||
if (y1 < y2) {
|
||||
yi = 1;
|
||||
dy = y2 - y1;
|
||||
} else {
|
||||
yi = -1;
|
||||
dy = y1 - y2;
|
||||
}
|
||||
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
|
||||
if (!dx && !dy) {
|
||||
/* single point - already all done */
|
||||
;
|
||||
} else if (dx > dy) {
|
||||
ai = (dy - dx) * 2;
|
||||
bi = dy * 2;
|
||||
d0 = bi - dx;
|
||||
do {
|
||||
if (d0 >= 0) {
|
||||
y1 += yi;
|
||||
d0 += ai;
|
||||
} else
|
||||
d0 += bi;
|
||||
x1 += xi;
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
} while (x1 != x2);
|
||||
} else {
|
||||
ai = (dx - dy) * 2;
|
||||
bi = dx * 2;
|
||||
d0 = bi - dy;
|
||||
do {
|
||||
if (d0 >= 0) {
|
||||
x1 += xi;
|
||||
d0 += ai;
|
||||
} else
|
||||
d0 += bi;
|
||||
y1 += yi;
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
} while (y1 != y2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
selection_do_randline(
|
||||
coordxy x1, coordxy y1,
|
||||
coordxy x2, coordxy y2,
|
||||
schar rough,
|
||||
schar rec,
|
||||
struct selectionvar *ov)
|
||||
{
|
||||
int mx, my;
|
||||
int dx, dy;
|
||||
|
||||
if (rec < 1 || (x2 == x1 && y2 == y1))
|
||||
return;
|
||||
|
||||
if (rough > max(abs(x2 - x1), abs(y2 - y1)))
|
||||
rough = max(abs(x2 - x1), abs(y2 - y1));
|
||||
|
||||
if (rough < 2) {
|
||||
mx = ((x1 + x2) / 2);
|
||||
my = ((y1 + y2) / 2);
|
||||
} else {
|
||||
do {
|
||||
dx = rn2(rough) - (rough / 2);
|
||||
dy = rn2(rough) - (rough / 2);
|
||||
mx = ((x1 + x2) / 2) + dx;
|
||||
my = ((y1 + y2) / 2) + dy;
|
||||
} while ((mx > COLNO - 1 || mx < 0 || my < 0 || my > ROWNO - 1));
|
||||
}
|
||||
|
||||
if (!selection_getpoint(mx, my, ov)) {
|
||||
selection_setpoint(mx, my, ov, 1);
|
||||
}
|
||||
|
||||
rough = (rough * 2) / 3;
|
||||
|
||||
rec--;
|
||||
|
||||
selection_do_randline(x1, y1, mx, my, rough, rec, ov);
|
||||
selection_do_randline(mx, my, x2, y2, rough, rec, ov);
|
||||
|
||||
selection_setpoint(x2, y2, ov, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
selection_iterate(
|
||||
struct selectionvar *ov,
|
||||
select_iter_func func,
|
||||
genericptr_t arg)
|
||||
{
|
||||
coordxy x, y;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (isok(x,y) && selection_getpoint(x, y, ov))
|
||||
(*func)(x, y, arg);
|
||||
}
|
||||
|
||||
/* change map location terrain type during level creation */
|
||||
static void
|
||||
sel_set_ter(coordxy x, coordxy y, genericptr_t arg)
|
||||
@@ -6938,27 +6208,6 @@ TODO: gc.coder->croom needs to be updated
|
||||
|
||||
RESTORE_WARNING_UNREACHABLE_CODE
|
||||
|
||||
struct selectionvar *
|
||||
selection_from_mkroom(struct mkroom *croom)
|
||||
{
|
||||
struct selectionvar *sel = selection_new();
|
||||
coordxy x, y;
|
||||
unsigned rmno;
|
||||
|
||||
if (!croom && gc.coder && gc.coder->croom)
|
||||
croom = gc.coder->croom;
|
||||
if (!croom)
|
||||
return sel;
|
||||
|
||||
rmno = (unsigned)((croom - gr.rooms) + ROOMOFFSET);
|
||||
for (y = croom->ly; y <= croom->hy; y++)
|
||||
for (x = croom->lx; x <= croom->hx; x++)
|
||||
if (isok(x, y) && !levl[x][y].edge
|
||||
&& levl[x][y].roomno == rmno)
|
||||
selection_setpoint(x, y, sel, 1);
|
||||
return sel;
|
||||
}
|
||||
|
||||
void
|
||||
update_croom(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user