diff options
Diffstat (limited to 'apps/plugins/xrick/util.c')
-rw-r--r-- | apps/plugins/xrick/util.c | 230 |
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 | */ | ||
36 | bool | ||
37 | u_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 | */ | ||
60 | bool | ||
61 | u_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 | */ | ||
91 | void | ||
92 | u_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 | */ | ||
193 | bool | ||
194 | u_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 | */ | ||
213 | char * | ||
214 | u_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 */ | ||