fastutils.xs
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:7k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. /* Utility functions rewritten in C for speed */
  2. #include "EXTERN.h"
  3. #include "perl.h"
  4. #include "XSUB.h"
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <string>
  8. typedef double (*NVtime_t) ();
  9. static void *NVtime = NULL;
  10. using namespace std;
  11. MODULE = FastUtils PACKAGE = Utils
  12. PROTOTYPES: ENABLE
  13. SV *
  14. binFind(r_array, ID)
  15. SV *r_array
  16. SV *ID
  17. INIT:
  18. int ok;
  19. SV *ref;
  20. AV *array;
  21. I32 len;
  22. CODE:
  23. /* Sanity check */
  24. ok = SvOK (r_array);
  25. if (ok) {
  26. ref = SvRV (r_array);
  27. ok = SvTYPE (ref) == SVt_PVAV;
  28. }
  29. if (ok) {
  30. array = (AV *) SvRV (r_array);
  31. len = av_len (array);
  32. if (len < 0)
  33. ok = 0;
  34. }
  35. if (ok) {
  36. I32 i;
  37. int found = 0;
  38. char *IDstr;
  39. STRLEN IDlen;
  40. /* Loop through the array and stop if one item matches */
  41. IDstr = SvPV (ID, IDlen);
  42. for (i = 0; i <= len; i++) {
  43. SV **currentSV;
  44. char *current;
  45. STRLEN currentlen;
  46. currentSV = av_fetch (array, i, 0);
  47. if (!currentSV)
  48. continue;
  49. current = SvPV (*currentSV, currentlen);
  50. if (currentlen == IDlen && memcmp (current, IDstr, currentlen) == 0) {
  51. found = 1;
  52. break;
  53. }
  54. }
  55. if (found)
  56. RETVAL = newSViv (i);
  57. else
  58. XSRETURN_UNDEF;
  59. } else
  60. XSRETURN_UNDEF;
  61. OUTPUT:
  62. RETVAL
  63. int
  64. timeOut(r_time, compare_time = NULL)
  65. SV *r_time
  66. SV *compare_time
  67. PREINIT:
  68. NV current_time, v_time, v_timeout;
  69. CODE:
  70. if (compare_time) {
  71. /* r_time is a number */
  72. if (!(v_time = SvNV (r_time)))
  73. XSRETURN_YES;
  74. if (!(v_timeout = SvNV (compare_time)))
  75. XSRETURN_YES;
  76. if (!NVtime) {
  77. SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
  78. if (!svp)
  79. croak("Time::HiRes is required");
  80. if (!SvIOK (*svp))
  81. croak("Time::NVtime isn't a function pointer");
  82. NVtime = INT2PTR (void *, SvIV (*svp));
  83. }
  84. current_time = ((NVtime_t) NVtime) ();
  85. } else {
  86. /* r_time is a hash */
  87. HV *hash;
  88. SV **sv_time, **sv_timeout;
  89. if (!r_time || !SvOK (r_time) || !SvTYPE (r_time) == SVt_PV)
  90. XSRETURN_YES;
  91. if (!(hash = (HV *) SvRV (r_time)))
  92. XSRETURN_YES;
  93. if (!(sv_time = hv_fetch (hash, "time", 4, 0)) || !(v_time = SvNV (*sv_time)))
  94. XSRETURN_YES;
  95. if (!(sv_timeout = hv_fetch (hash, "timeout", 7, 0)) || !(v_timeout = SvNV (*sv_timeout)))
  96. XSRETURN_YES;
  97. if (!NVtime) {
  98. SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
  99. if (!svp)
  100. croak("Time::HiRes is required");
  101. if (!SvIOK (*svp))
  102. croak("Time::NVtime isn't a function pointer");
  103. NVtime = INT2PTR (void *, SvIV (*svp));
  104. }
  105. current_time = ((NVtime_t) NVtime) ();
  106. }
  107. RETVAL = (current_time - v_time > v_timeout);
  108. OUTPUT:
  109. RETVAL
  110. char *
  111. xpmmake(width, height, field_data)
  112. int width
  113. int height
  114. char *field_data
  115. CODE:
  116. // Create an XPM from raw field data.
  117. // Written in C++ for speed.
  118. string data;
  119. int y, x;
  120. char tmp[10], *buf, *line;
  121. data.reserve (width * height + 1024);
  122. data.append (
  123. "/* XPM */n"
  124. "static char * my_xpm[] = {n"
  125. """);
  126. snprintf (tmp, sizeof (tmp), "%d %d", width, height);
  127. data.append (tmp);
  128. data.append (" 8 1",n"
  129. ""Atc #F4F4F4",n"
  130. ""Btc #505050",n"
  131. ""Ctc #6060B0",n"
  132. ""Dtc #8080B0",n"
  133. ""Etc #7070B0",n"
  134. ""Ftc #B0B0B0",n"
  135. ""Gtc #808080",n"
  136. ""Htc #600000",n");
  137. line = (char *) malloc (width);
  138. for (y = height - 1; y >= 0; y--) {
  139. for (x = 0; x < width; x++) {
  140. switch (field_data[y * width + x]) {
  141. case '':
  142. line[x] = 'A';
  143. break;
  144. case '1':
  145. line[x] = 'B';
  146. break;
  147. case '2':
  148. line[x] = 'C';
  149. break;
  150. case '3':
  151. line[x] = 'D';
  152. break;
  153. case '4':
  154. line[x] = 'E';
  155. break;
  156. case '5':
  157. line[x] = 'F';
  158. break;
  159. case '6':
  160. line[x] = 'G';
  161. break;
  162. default:
  163. line[x] = 'H';
  164. break;
  165. }
  166. }
  167. data.append (""");
  168. data.append (line, width);
  169. data.append ("",n");
  170. }
  171. free (line);
  172. data.append ("};n");
  173. // I hope sizeof(char) == 1...
  174. New (0, buf, data.size () + 1, char);
  175. Copy (data.c_str (), buf, data.size (), char);
  176. buf[data.size ()] = '';
  177. RETVAL = buf;
  178. OUTPUT:
  179. RETVAL
  180. SV *
  181. makeDistMap(rawMap, width, height)
  182. SV *rawMap
  183. int width
  184. int height
  185. INIT:
  186. STRLEN len;
  187. int i, x, y;
  188. int dist, val;
  189. unsigned char *c_rawMap, *data;
  190. bool done;
  191. CODE:
  192. if (!SvOK (rawMap))
  193. XSRETURN_UNDEF;
  194. c_rawMap = (unsigned char *) SvPV (rawMap, len);
  195. if ((int) len != width * height)
  196. XSRETURN_UNDEF;
  197. /* Simplify the raw map data. Each byte in the raw map data
  198.    represents a block on the field, but only some bytes are
  199.    interesting to pathfinding. */
  200. New (0, data, len, unsigned char);
  201. Copy (c_rawMap, data, len, unsigned char);
  202. for (i = 0; i < (int) len; i++) {
  203. // 0 is open, 3 is walkable water
  204. switch (data[i]) {
  205. case 0:
  206. case 3:
  207. data[i] = 255;
  208. break;
  209. default:
  210. data[i] = 0;
  211. break;
  212. }
  213. }
  214. done = false;
  215. while (!done) {
  216. done = true;
  217. // 'push' wall distance right and up
  218. for (y = 0; y < height; y++) {
  219. for (x = 0; x < width; x++) {
  220. i = y * width + x;
  221. dist = data[i];
  222. if (x != width - 1) {
  223. int ir = y * width + x + 1;
  224. int distr = (int) data[ir];
  225. int comp = dist - distr;
  226. if (comp > 1) {
  227. val = distr + 1;
  228. if (val > 255)
  229. val = 255;
  230. data[i] = val;
  231. done = false;
  232. } else if (comp < -1) {
  233. val = dist + 1;
  234. if (val > 255)
  235. val = 255;
  236. data[ir] = val;
  237. done = false;
  238. }
  239. }
  240. if (y != height - 1) {
  241. int iu = (y + 1) * width + x;
  242. int distu = (int) data[iu];
  243. int comp = dist - distu;
  244. if (comp > 1) {
  245. int val = distu + 1;
  246. if (val > 255)
  247. val = 255;
  248. data[i] = (char) val;
  249. done = false;
  250. } else if (comp < -1) {
  251. int val = dist + 1;
  252. if (val > 255)
  253. val = 255;
  254. data[iu] = (char) val;
  255. done = true;
  256. }
  257. }
  258. }
  259. }
  260. // 'push' wall distance left and down
  261. for (y = height - 1; y >= 0; y--) {
  262. for (x = width - 1; x >= 0 ; x--) {
  263. i = y * width + x;
  264. dist = data[i];
  265. if (x != 0) {
  266. int il = y * width + x - 1;
  267. int distl = data[il];
  268. int comp = dist - distl;
  269. if (comp > 1) {
  270. val = distl + 1;
  271. if (val > 255)
  272. val = 255;
  273. data[i] = val;
  274. done = false;
  275. } else if (comp < -1) {
  276. val = dist + 1;
  277. if (val > 255)
  278. val = 255;
  279. data[il] = val;
  280. done = false;
  281. }
  282. }
  283. if (y != 0) {
  284. int id = (y - 1) * width + x;
  285. int distd = data[id];
  286. int comp = dist - distd;
  287. if (comp > 1) {
  288. val = distd + 1;
  289. if (val > 255)
  290. val = 255;
  291. data[i] = val;
  292. done = false;
  293. } else if (comp < -1) {
  294. val = dist + 1;
  295. if (val > 255)
  296. val = 255;
  297. data[id] = val;
  298. done = false;
  299. }
  300. }
  301. }
  302. }
  303. }
  304. RETVAL = newSVpv ((const char *) data, len);
  305. OUTPUT:
  306. RETVAL