]> git.pond.sub.org Git - empserver/blob - src/lib/common/xy.c
License upgrade to GPL version 3 or later
[empserver] / src / lib / common / xy.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2011, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
6  *  Empire 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 3 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, see <http://www.gnu.org/licenses/>.
18  *
19  *  ---
20  *
21  *  See files README, COPYING and CREDITS in the root of the source
22  *  tree for related information and legal notices.  It is expected
23  *  that future projects/authors will amend these files as needed.
24  *
25  *  ---
26  *
27  *  xy.c: x-y related conversion routines
28  *
29  *  Known contributors to this file:
30  *     Dave Pare, 1989
31  *     Markus Armbruster, 2004-2008
32  */
33
34 #include <config.h>
35
36 #include <errno.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include "file.h"
40 #include "misc.h"
41 #include "nat.h"
42 #include "optlist.h"
43 #include "prototypes.h"
44 #include "sect.h"
45 #include "xy.h"
46
47 /*
48  * return pointer to a string containing the x,y
49  * coords as desired by a particular target country.
50  */
51 char *
52 xyas(coord x, coord y, natid country)
53 {
54     struct natstr *np;
55
56     np = getnatp(country);
57     return prbuf("%d,%d", xrel(np, x), yrel(np, y));
58 }
59
60 char *
61 ownxy(struct sctstr *sp)
62 {
63     return xyas(sp->sct_x, sp->sct_y, sp->sct_own);
64 }
65
66 coord
67 xrel(struct natstr *np, coord absx)
68 {
69     coord x;
70
71     x = XNORM(absx - np->nat_xorg);
72     if (x >= WORLD_X / 2)
73         x -= WORLD_X;
74     return x;
75 }
76
77 coord
78 yrel(struct natstr *np, coord absy)
79 {
80     coord y;
81
82     y = YNORM(absy - np->nat_yorg);
83     if (y >= WORLD_Y / 2)
84         y -= WORLD_Y;
85     return y;
86 }
87
88 void
89 xyrelrange(struct natstr *np, struct range *src, struct range *dst)
90 {
91     dst->lx = xrel(np, src->lx);
92     dst->hx = xrel(np, src->hx);
93     dst->ly = yrel(np, src->ly);
94     dst->hy = yrel(np, src->hy);
95     dst->width = src->width;
96     dst->height = src->height;
97 }
98
99 void
100 xyabsrange(struct natstr *np, struct range *src, struct range *dst)
101 {
102     dst->lx = xabs(np, src->lx);
103     dst->hx = xabs(np, src->hx);
104     dst->ly = yabs(np, src->ly);
105     dst->hy = yabs(np, src->hy);
106     dst->width = src->width;
107     dst->height = src->height;
108 }
109
110 /*
111  * Convert initial part of STR to normalized x-coordinate.
112  * Return -1 on error.  This works, as normalized coordinates are
113  * non-negative.
114  * Assign pointer to first character after the coordinate to *END,
115  * unless END is a null pointer.
116  */
117 coord
118 strtox(char *str, char **end)
119 {
120     long l;
121
122     errno = 0;
123     l = strtol(str, end, 10);
124     if (*end == str || errno != 0)
125         return -1;
126     return XNORM(l);
127 }
128
129 /*
130  * Convert initial part of STR to normalized y-coordinate.
131  * Return -1 on error.  This works, as normalized coordinates are
132  * non-negative.
133  * Assign pointer to first character after the coordinate to *END,
134  * unless END is a null pointer.
135  */
136 coord
137 strtoy(char *str, char **end)
138 {
139     long l;
140
141     errno = 0;
142     l = strtol(str, end, 10);
143     if (*end == str || errno != 0)
144         return -1;
145     return YNORM(l);
146 }
147
148 coord
149 xabs(struct natstr *np, coord relx)
150 {
151     relx += np->nat_xorg;
152     return XNORM(relx);
153 }
154
155 coord
156 yabs(struct natstr *np, coord rely)
157 {
158     rely += np->nat_yorg;
159     return YNORM(rely);
160 }
161
162 int
163 sctoff(coord x, coord y)
164 {
165     if (CANT_HAPPEN((x + y) & 1))
166         return -1;
167     return XYOFFSET(XNORM(x), YNORM(y));
168 }
169
170 coord
171 xnorm(coord x)
172 {
173     return XNORM(x);
174 }
175
176 coord
177 ynorm(coord y)
178 {
179     return YNORM(y);
180 }
181
182 int
183 xyinrange(coord x, coord y, struct range *rp)
184 {
185     if (rp->lx <= rp->hx) {
186         /* xrange doesn't wrap */
187         if (x < rp->lx || x > rp->hx)
188             return 0;
189     } else {
190         if (x < rp->lx && x > rp->hx)
191             return 0;
192     }
193     if (rp->ly <= rp->hy) {
194         /* yrange doesn't wrap */
195         if (y < rp->ly || y > rp->hy)
196             return 0;
197     } else {
198         if (y < rp->ly && y > rp->hy)
199             return 0;
200     }
201     return 1;
202 }
203
204
205 char *
206 prbuf(char *format, ...)
207 {
208     static int nbuf = -1;
209     static char buf[20][1024];
210     va_list ap;
211
212     if (++nbuf > 19)
213         nbuf = 0;
214
215     va_start(ap, format);
216     (void)vsprintf(buf[nbuf], format, ap);
217     va_end(ap);
218
219     return buf[nbuf];
220 }