Source:NetHack 3.4.3/src/rect.c

From NetHackWiki
Revision as of 19:23, 31 January 2011 by Paxedbot (talk | contribs) (moved Source:Rect.c to Source:NetHack 3.4.3/src/rect.c: Moving src to subdirs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to src/rect.c from NetHack 3.4.3. To link to a particular line, write [[rect.c#line123]], for example.

Top of file

/*	SCCS Id: @(#)rect.c	3.4	1990/02/22	*/
/* Copyright (c) 1990 by Jean-Christophe Collet	 */
/* NetHack may be freely redistributed.  See license for details. */

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

#include "hack.h"

int FDECL(get_rect_ind, (NhRect *));

static boolean FDECL(intersect, (NhRect *,NhRect *,NhRect *));

/*
* In this file, we will handle the various rectangle functions we
* need for room generation.
*/

#define MAXRECT	50
#define XLIM	4
#define YLIM	3

static NhRect rect[MAXRECT+1];
static int rect_cnt;

/*
* Initialisation of internal structures. Should be called for every
* new level to be build...
*/

init_rect

void
init_rect()
{
	rect_cnt = 1;
	rect[0].lx = rect[0].ly = 0;
	rect[0].hx = COLNO - 1;
	rect[0].hy = ROWNO - 1;
}

get_rect_ind

/*
* Search Index of one precise NhRect.
*
*/

int
get_rect_ind(r)
NhRect *r;
{
	register NhRect *rectp;
	register int lx, ly, hx, hy;
	register int i;

	lx = r->lx; ly = r->ly;
	hx = r->hx; hy = r->hy;
	for (i=0,rectp = &rect[0];i<rect_cnt;i++,rectp++)
	    if ( lx == rectp->lx && ly == rectp->ly &&
		 hx == rectp->hx && hy == rectp->hy)
		return i;
	return -1;
}

get_rect

/*
* Search a free rectangle that include the one given in arg
*/

NhRect *
get_rect(r)
NhRect *r;
{
	register NhRect *rectp;
	register int lx, ly, hx, hy;
	register int i;

	lx = r->lx; ly = r->ly;
	hx = r->hx; hy = r->hy;
	for (i=0,rectp = &rect[0];i<rect_cnt;i++,rectp++)
	    if ( lx >= rectp->lx && ly >= rectp->ly &&
		 hx <= rectp->hx && hy <= rectp->hy)
		return rectp;
	return 0;
}

rnd_rect

/*
* Get some random NhRect from the list.
*/

NhRect *
rnd_rect()
{
	    return rect_cnt > 0 ? &rect[rn2(rect_cnt)] : 0;
}

intersect

/*
* Search intersection between two rectangles (r1 & r2).
* return TRUE if intersection exist and put it in r3.
* otherwise returns FALSE
*/

static boolean
intersect(r1, r2, r3)
NhRect *r1, *r2, *r3;
{
	if (r2->lx > r1->hx || r2->ly > r1->hy ||
	    r2->hx < r1->lx || r2->hy < r1->ly)
	    return FALSE;

	r3->lx = (r2->lx > r1->lx ? r2->lx : r1->lx);
	r3->ly = (r2->ly > r1->ly ? r2->ly : r1->ly);
	r3->hx = (r2->hx > r1->hx ? r1->hx : r2->hx);
	r3->hy = (r2->hy > r1->hy ? r1->hy : r2->hy);

	if (r3->lx > r3->hx || r3->ly > r3->hy)
	    return FALSE;
	return TRUE;
}

remove_rect

/*
* Remove a rectangle from the list of free NhRect.
*/

void
remove_rect(r)
NhRect *r;
{
	int ind;

	ind = get_rect_ind(r);
	if ( ind >=0 )
	    rect[ind] = rect[--rect_cnt];
}

add_rect

/*
* Add a NhRect to the list.
*/

void
add_rect(r)
NhRect *r;
{
	if (rect_cnt >= MAXRECT) {
#ifdef WIZARD
		if (wizard) pline("MAXRECT may be too small.");
#endif
		return;
	}
	/* Check that this NhRect is not included in another one */
	if (get_rect(r))
	    return;
	rect[rect_cnt] = *r;
	rect_cnt++;
}

split_rects

/*
* Okay, here we have two rectangles (r1 & r2).
* r1 was already in the list and r2 is included in r1.
* What we want is to allocate r2, that is split r1 into smaller rectangles
* then remove it.
*/

void
split_rects(r1, r2)
NhRect *r1, *r2;
{
	NhRect r, old_r;
	int i;

	old_r = *r1;
	remove_rect(r1);

	/* Walk down since rect_cnt & rect[] will change... */
	for (i=rect_cnt-1; i>=0; i--)
	    if (intersect(&rect[i], r2, &r))
		split_rects(&rect[i], &r);
	
	if (r2->ly - old_r.ly-1 > (old_r.hy < ROWNO - 1 ? 2*YLIM : YLIM+1)+4) {
		r = old_r;
		r.hy = r2->ly - 2;
		add_rect(&r);
	}
	if (r2->lx - old_r.lx-1 > (old_r.hx < COLNO - 1 ? 2*XLIM : XLIM+1)+4) {
		r = old_r;
		r.hx = r2->lx - 2;
		add_rect(&r);
	}
	if (old_r.hy - r2->hy-1 > (old_r.ly > 0 ? 2*YLIM : YLIM+1)+4) {
		r = old_r;
		r.ly = r2->hy + 2;
		add_rect(&r);
	}
	if (old_r.hx - r2->hx-1 > (old_r.lx > 0 ? 2*XLIM : XLIM+1)+4) {
		r = old_r;
		r.lx = r2->hx + 2;
		add_rect(&r);
	}
}

/*rect.c*/