]> git.pond.sub.org Git - empserver/blob - src/lib/common/xy.c
Update copyright notice.
[empserver] / src / lib / common / xy.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  xy.c: x-y related conversion routines
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1989
32  */
33
34 #include <config.h>
35
36 #include <ctype.h>
37 #include <errno.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include "file.h"
41 #include "misc.h"
42 #include "nat.h"
43 #include "optlist.h"
44 #include "prototypes.h"
45 #include "sect.h"
46 #include "xy.h"
47
48 /*
49  * return pointer to a string containing the x,y
50  * coords as desired by a particular target country.
51  */
52 char *
53 xyas(coord x, coord y, natid country)
54 {
55     struct natstr *np;
56
57     np = getnatp(country);
58     return prbuf("%d,%d", xrel(np, x), yrel(np, y));
59 }
60
61 char *
62 ownxy(struct sctstr *sp)
63 {
64     return xyas(sp->sct_x, sp->sct_y, sp->sct_own);
65 }
66
67 coord
68 xrel(struct natstr *np, coord absx)
69 {
70     coord x;
71
72     x = XNORM(absx - np->nat_xorg);
73     if (x >= WORLD_X / 2)
74         x -= WORLD_X;
75     else if (x < -WORLD_X / 2)
76         x += WORLD_X;
77     return x;
78 }
79
80 coord
81 yrel(struct natstr *np, coord absy)
82 {
83     coord y;
84
85     y = YNORM(absy - np->nat_yorg);
86     if (y >= WORLD_Y / 2)
87         y -= WORLD_Y;
88     else if (y < -WORLD_Y / 2)
89         y += WORLD_Y;
90     return y;
91 }
92
93 void
94 xyrelrange(struct natstr *np, struct range *src, struct range *dst)
95 {
96     dst->lx = xrel(np, src->lx);
97     dst->hx = xrel(np, src->hx);
98     dst->ly = yrel(np, src->ly);
99     dst->hy = yrel(np, src->hy);
100     dst->width = src->width;
101     dst->height = src->height;
102 }
103
104 void
105 xyabsrange(struct natstr *np, struct range *src, struct range *dst)
106 {
107     dst->lx = xabs(np, src->lx);
108     dst->hx = xabs(np, src->hx);
109     dst->ly = yabs(np, src->ly);
110     dst->hy = yabs(np, src->hy);
111     dst->width = src->width;
112     dst->height = src->height;
113 }
114
115 /*
116  * Convert initial part of STR to normalized x-coordinate.
117  * Return -1 on error.  This works, as normalized coordinates are
118  * non-negative.
119  * Assign pointer to first character after the coordinate to *END,
120  * unless END is a null pointer.
121  */
122 coord
123 strtox(char *str, char **end)
124 {
125     long l;
126
127     errno = 0;
128     l = strtol(str, end, 10);
129     if (*end == str || errno != 0)
130         return -1;
131     return XNORM(l);
132 }
133
134 /*
135  * Convert initial part of STR to normalized y-coordinate.
136  * Return -1 on error.  This works, as normalized coordinates are
137  * non-negative.
138  * Assign pointer to first character after the coordinate to *END,
139  * unless END is a null pointer.
140  */
141 coord
142 strtoy(char *str, char **end)
143 {
144     long l;
145
146     errno = 0;
147     l = strtol(str, end, 10);
148     if (*end == str || errno != 0)
149         return -1;
150     return YNORM(l);
151 }
152
153 coord
154 xabs(struct natstr *np, coord relx)
155 {
156     relx += np->nat_xorg;
157     return XNORM(relx);
158 }
159
160 coord
161 yabs(struct natstr *np, coord rely)
162 {
163     rely += np->nat_yorg;
164     return YNORM(rely);
165 }
166
167 int
168 sctoff(coord x, coord y)
169 {
170     if ((x + y) & 01) {
171         logerror("%d,%d is an invalid sector specification!\n", x, y);
172         return -1;
173     }
174     return (YNORM(y) * WORLD_X + XNORM(x)) / 2;
175 }
176
177 coord
178 xnorm(coord x)
179 {
180     if (x < 0)
181         x = WORLD_X - (-x % WORLD_X);
182     return x % WORLD_X;
183 }
184
185 coord
186 ynorm(coord y)
187 {
188     if (y < 0)
189         y = WORLD_Y - (-y % WORLD_Y);
190     return y % WORLD_Y;
191 }
192
193 int
194 xyinrange(coord x, coord y, struct range *rp)
195 {
196     if (rp->lx < rp->hx) {
197         /* xrange doesn't wrap */
198         if (x < rp->lx || x > rp->hx)
199             return 0;
200     } else {
201         if (x < rp->lx && x > rp->hx)
202             return 0;
203     }
204     if (rp->ly < rp->hy) {
205         /* yrange doesn't wrap */
206         if (y < rp->ly || y > rp->hy)
207             return 0;
208     } else {
209         if (y < rp->ly && y > rp->hy)
210             return 0;
211     }
212     return 1;
213 }
214
215
216 char *
217 prbuf(char *format, ...)
218 {
219     static int nbuf = -1;
220     static char buf[20][1024];
221     va_list ap;
222
223     if (++nbuf > 19)
224         nbuf = 0;
225
226     va_start(ap, format);
227     (void)vsprintf(buf[nbuf], format, ap);
228     va_end(ap);
229
230     return buf[nbuf];
231 }