1 /* NetHack 3.7 rect.c $NHDT-Date: 1596498203 2020/08/03 23:43:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */
2 /* Copyright (c) 1990 by Jean-Christophe Collet */
3 /* NetHack may be freely redistributed. See license for details. */
7 int get_rect_ind(NhRect
*);
9 staticfn boolean
intersect(NhRect
*, NhRect
*, NhRect
*);
12 * In this file, we will handle the various rectangle functions we
13 * need for room generation.
19 static NhRect
*rect
= (NhRect
*) 0;
20 static int n_rects
= 0;
24 * Initialization of internal structures. Should be called for every
25 * new level to be build...
32 n_rects
= (COLNO
* ROWNO
) / 30;
33 rect
= (NhRect
*) alloc(sizeof(NhRect
) * n_rects
);
35 panic("Could not alloc rect");
39 rect
[0].lx
= rect
[0].ly
= 0;
40 rect
[0].hx
= COLNO
- 1;
41 rect
[0].hy
= ROWNO
- 1;
50 n_rects
= rect_cnt
= 0;
55 * Search Index of one precise NhRect.
60 get_rect_ind(NhRect
*r
)
70 for (i
= 0, rectp
= &rect
[0]; i
< rect_cnt
; i
++, rectp
++)
71 if (lx
== rectp
->lx
&& ly
== rectp
->ly
&& hx
== rectp
->hx
78 * Search a free rectangle that include the one given in arg
92 for (i
= 0, rectp
= &rect
[0]; i
< rect_cnt
; i
++, rectp
++)
93 if (lx
>= rectp
->lx
&& ly
>= rectp
->ly
&& hx
<= rectp
->hx
100 * Get some random NhRect from the list.
106 return rect_cnt
> 0 ? &rect
[rn2(rect_cnt
)] : 0;
110 * Search intersection between two rectangles (r1 & r2).
111 * return TRUE if intersection exist and put it in r3.
112 * otherwise returns FALSE
116 intersect(NhRect
*r1
, NhRect
*r2
, NhRect
*r3
)
118 if (r2
->lx
> r1
->hx
|| r2
->ly
> r1
->hy
|| r2
->hx
< r1
->lx
122 r3
->lx
= (r2
->lx
> r1
->lx
? r2
->lx
: r1
->lx
);
123 r3
->ly
= (r2
->ly
> r1
->ly
? r2
->ly
: r1
->ly
);
124 r3
->hx
= (r2
->hx
> r1
->hx
? r1
->hx
: r2
->hx
);
125 r3
->hy
= (r2
->hy
> r1
->hy
? r1
->hy
: r2
->hy
);
127 if (r3
->lx
> r3
->hx
|| r3
->ly
> r3
->hy
)
132 /* Put the rectangle containing both r1 and r2 into r3 */
134 rect_bounds(NhRect r1
, NhRect r2
, NhRect
*r3
)
136 r3
->lx
= min(r1
.lx
, r2
.lx
);
137 r3
->ly
= min(r1
.ly
, r2
.ly
);
138 r3
->hx
= max(r1
.hx
, r2
.hx
);
139 r3
->hy
= max(r1
.hy
, r2
.hy
);
143 * Remove a rectangle from the list of free NhRect.
147 remove_rect(NhRect
*r
)
151 ind
= get_rect_ind(r
);
153 rect
[ind
] = rect
[--rect_cnt
];
157 * Add a NhRect to the list.
163 if (rect_cnt
>= n_rects
) {
164 impossible("n_rects may be too small.");
167 /* Check that this NhRect is not included in another one */
175 * Okay, here we have two rectangles (r1 & r2).
176 * r1 was already in the list and r2 is included in r1.
177 * What we want is to allocate r2, that is split r1 into smaller rectangles
182 split_rects(NhRect
*r1
, NhRect
*r2
)
190 /* Walk down since rect_cnt & rect[] will change... */
191 for (i
= rect_cnt
- 1; i
>= 0; i
--)
192 if (intersect(&rect
[i
], r2
, &r
))
193 split_rects(&rect
[i
], &r
);
195 if (r2
->ly
- old_r
.ly
- 1
196 > (old_r
.hy
< ROWNO
- 1 ? 2 * YLIM
: YLIM
+ 1) + 4) {
201 if (r2
->lx
- old_r
.lx
- 1
202 > (old_r
.hx
< COLNO
- 1 ? 2 * XLIM
: XLIM
+ 1) + 4) {
207 if (old_r
.hy
- r2
->hy
- 1 > (old_r
.ly
> 0 ? 2 * YLIM
: YLIM
+ 1) + 4) {
212 if (old_r
.hx
- r2
->hx
- 1 > (old_r
.lx
> 0 ? 2 * XLIM
: XLIM
+ 1) + 4) {