summaryrefslogtreecommitdiff
path: root/apps/plugins/xrick/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/xrick/util.c')
-rw-r--r--apps/plugins/xrick/util.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/apps/plugins/xrick/util.c b/apps/plugins/xrick/util.c
new file mode 100644
index 0000000000..8926a00e5d
--- /dev/null
+++ b/apps/plugins/xrick/util.c
@@ -0,0 +1,230 @@
1/*
2 * xrick/util.c
3 *
4 * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net).
5 * Copyright (C) 2008-2014 Pierluigi Vicinanza.
6 * All rights reserved.
7 *
8 * The use and distribution terms for this software are contained in the file
9 * named README, which can be found in the root of this distribution. By
10 * using this software in any fashion, you are agreeing to be bound by the
11 * terms of this license.
12 *
13 * You must not remove this notice, or any other, from this software.
14 */
15
16#include "xrick/util.h"
17
18#include "xrick/config.h"
19#include "xrick/game.h"
20#include "xrick/ents.h"
21#include "xrick/e_rick.h"
22#include "xrick/maps.h"
23#include "xrick/system/system.h"
24
25#include <string.h> /* memcpy */
26
27/*
28 * Full box test.
29 *
30 * ASM 1199
31 *
32 * e: entity to test against.
33 * x,y: coordinates to test.
34 * ret: true/(x,y) is within e's space, false/not.
35 */
36bool
37u_fboxtest(U8 e, S16 x, S16 y)
38{
39 if (ent_ents[e].x >= x ||
40 ent_ents[e].x + ent_ents[e].w < x ||
41 ent_ents[e].y >= y ||
42 ent_ents[e].y + ent_ents[e].h < y)
43 return false;
44 else
45 return true;
46}
47
48
49
50
51/*
52 * Box test (then whole e2 is checked agains the center of e1).
53 *
54 * ASM 113E
55 *
56 * e1: entity to test against (corresponds to DI in asm code).
57 * e2: entity to test (corresponds to SI in asm code).
58 * ret: true/intersect, false/not.
59 */
60bool
61u_boxtest(U8 e1, U8 e2)
62{
63 /* rick is special (may be crawling) */
64 if (e1 == E_RICK_NO)
65 return e_rick_boxtest(e2);
66
67 /*
68 * entity 1: x+0x05 to x+0x011, y to y+0x14
69 * entity 2: x to x+ .w, y to y+ .h
70 */
71 if (ent_ents[e1].x + 0x11 < ent_ents[e2].x ||
72 ent_ents[e1].x + 0x05 > ent_ents[e2].x + ent_ents[e2].w ||
73 ent_ents[e1].y + 0x14 < ent_ents[e2].y ||
74 ent_ents[e1].y > ent_ents[e2].y + ent_ents[e2].h - 1)
75 return false;
76 else
77 return true;
78}
79
80
81/*
82 * Compute the environment flag.
83 *
84 * ASM 0FBC if !crawl, else 103E
85 *
86 * x, y: coordinates where to compute the environment flag
87 * crawl: is rick crawling?
88 * rc0: anything CHANGED to the environment flag for crawling (6DBA)
89 * rc1: anything CHANGED to the environment flag (6DAD)
90 */
91void
92u_envtest(S16 x, S16 y, bool crawl, U8 *rc0, U8 *rc1)
93{
94 U8 i, xx;
95
96 /* prepare for ent #0 test */
97 ent_ents[ENT_ENTSNUM].x = x;
98 ent_ents[ENT_ENTSNUM].y = y;
99
100 i = 1;
101 if (!crawl) i++;
102 if (y & 0x0004) i++;
103
104 x += 4;
105 xx = (U8)x; /* FIXME? */
106
107 x = x >> 3; /* from pixels to tiles */
108 y = y >> 3; /* from pixels to tiles */
109
110 *rc0 = *rc1 = 0;
111
112 if (xx & 0x07) { /* tiles columns alignment */
113 if (crawl) {
114 *rc0 |= (map_eflg[map_map[y][x]] &
115 (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
116 *rc0 |= (map_eflg[map_map[y][x + 1]] &
117 (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
118 *rc0 |= (map_eflg[map_map[y][x + 2]] &
119 (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
120 y++;
121 }
122 do {
123 *rc1 |= (map_eflg[map_map[y][x]] &
124 (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
125 MAP_EFLG_LETHAL|MAP_EFLG_01));
126 *rc1 |= (map_eflg[map_map[y][x + 1]] &
127 (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
128 MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
129 *rc1 |= (map_eflg[map_map[y][x + 2]] &
130 (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
131 MAP_EFLG_LETHAL|MAP_EFLG_01));
132 y++;
133 } while (--i > 0);
134
135 *rc1 |= (map_eflg[map_map[y][x]] &
136 (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
137 MAP_EFLG_LETHAL|MAP_EFLG_01));
138 *rc1 |= (map_eflg[map_map[y][x + 1]]);
139 *rc1 |= (map_eflg[map_map[y][x + 2]] &
140 (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
141 MAP_EFLG_LETHAL|MAP_EFLG_01));
142 }
143 else {
144 if (crawl) {
145 *rc0 |= (map_eflg[map_map[y][x]] &
146 (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
147 *rc0 |= (map_eflg[map_map[y][x + 1]] &
148 (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
149 y++;
150 }
151 do {
152 *rc1 |= (map_eflg[map_map[y][x]] &
153 (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
154 MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
155 *rc1 |= (map_eflg[map_map[y][x + 1]] &
156 (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
157 MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
158 y++;
159 } while (--i > 0);
160
161 *rc1 |= (map_eflg[map_map[y][x]]);
162 *rc1 |= (map_eflg[map_map[y][x + 1]]);
163 }
164
165 /*
166 * If not lethal yet, and there's an entity on slot zero, and (x,y)
167 * boxtests this entity, then raise SOLID flag. This is how we make
168 * sure that no entity can move over the entity that is on slot zero.
169 *
170 * Beware! When game_cheat2 is set, this means that a block can
171 * move over rick without killing him -- but then rick is trapped
172 * because the block is solid.
173 */
174 if (!(*rc1 & MAP_EFLG_LETHAL)
175 && ent_ents[0].n
176 && u_boxtest(ENT_ENTSNUM, 0)) {
177 *rc1 |= MAP_EFLG_SOLID;
178 }
179
180 /* When game_cheat2 is set, the environment can not be lethal. */
181#ifdef ENABLE_CHEATS
182 if (game_cheat2) *rc1 &= ~MAP_EFLG_LETHAL;
183#endif
184}
185
186
187/*
188 * Check if x,y is within e trigger box.
189 *
190 * ASM 126F
191 * return: false if not in box, true if in box.
192 */
193bool
194u_trigbox(U8 e, S16 x, S16 y)
195{
196 U16 xmax, ymax;
197
198 xmax = ent_ents[e].trig_x + (ent_entdata[ent_ents[e].n & 0x7F].trig_w << 3);
199 ymax = ent_ents[e].trig_y + (ent_entdata[ent_ents[e].n & 0x7F].trig_h << 3);
200
201 if (xmax > 0xFF) xmax = 0xFF;
202
203 if (x <= ent_ents[e].trig_x || x > xmax ||
204 y <= ent_ents[e].trig_y || y > ymax)
205 return false;
206 else
207 return true;
208}
209
210/*
211 * Custom implementation of strdup function
212 */
213char *
214u_strdup(const char *sourceStr)
215{
216 char *destStr;
217 size_t length;
218
219 length = sys_strlen(sourceStr) + 1;
220 destStr = sysmem_push(length);
221 if (!destStr)
222 {
223 return NULL;
224 }
225 memcpy(destStr, sourceStr, length);
226 return destStr;
227}
228
229
230/* eof */