util.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. //
  2. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  3. // Portions Copyright (c) 2004, Pierre-Marie Baty.
  4. // Portions Copyright (c) 2009, netwan.
  5. //
  6. // All rights reserved.
  7. //
  8. // This file is part of SDLPAL.
  9. //
  10. // SDLPAL is free software: you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published by
  12. // the Free Software Foundation, either version 3 of the License, or
  13. // (at your option) any later version.
  14. //
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License
  21. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. //
  23. #include "util.h"
  24. #ifdef PAL_HAS_NATIVEMIDI
  25. #include "midi.h"
  26. #endif
  27. void
  28. trim(
  29. char *str
  30. )
  31. /*++
  32. Purpose:
  33. Remove the leading and trailing spaces in a string.
  34. Parameters:
  35. str - the string to proceed.
  36. Return value:
  37. None.
  38. --*/
  39. {
  40. int pos = 0;
  41. char *dest = str;
  42. //
  43. // skip leading blanks
  44. //
  45. while (str[pos] <= ' ' && str[pos] > 0)
  46. pos++;
  47. while (str[pos])
  48. {
  49. *(dest++) = str[pos];
  50. pos++;
  51. }
  52. *(dest--) = '\0'; // store the null
  53. //
  54. // remove trailing blanks
  55. //
  56. while (dest >= str && *dest <= ' ' && *dest > 0)
  57. *(dest--) = '\0';
  58. }
  59. char *
  60. va(
  61. const char *format,
  62. ...
  63. )
  64. /*++
  65. Purpose:
  66. Does a varargs printf into a temp buffer, so we don't need to have
  67. varargs versions of all text functions.
  68. Parameters:
  69. format - the format string.
  70. Return value:
  71. Pointer to the result string.
  72. --*/
  73. {
  74. static char string[256];
  75. va_list argptr;
  76. va_start(argptr, format);
  77. vsnprintf(string, 256, format, argptr);
  78. va_end(argptr);
  79. return string;
  80. }
  81. /*
  82. * RNG code based on RACC by Pierre-Marie Baty.
  83. * http://racc.bots-united.com
  84. *
  85. * Copyright (c) 2004, Pierre-Marie Baty
  86. * All rights reserved.
  87. *
  88. * Redistribution and use in source and binary forms, with or
  89. * without modification, are permitted provided that the following
  90. * conditions are met:
  91. *
  92. * Redistributions of source code must retain the above copyright
  93. * notice, this list of conditions and the following disclaimer.
  94. *
  95. * Redistributions in binary form must reproduce the above copyright
  96. * notice, this list of conditions and the following disclaimer in
  97. * the documentation and/or other materials provided with the
  98. * distribution.
  99. *
  100. * Neither the name of the RACC nor the names of its contributors
  101. * may be used to endorse or promote products derived from this
  102. * software without specific prior written permission.
  103. *
  104. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  105. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  106. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  107. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  108. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  109. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  110. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  111. * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  112. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  113. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  114. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  115. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  116. * POSSIBILITY OF SUCH DAMAGE.
  117. */
  118. //
  119. // Our random number generator's seed.
  120. //
  121. static int glSeed = 0;
  122. static void
  123. lsrand(
  124. unsigned int iInitialSeed
  125. )
  126. /*++
  127. Purpose:
  128. This function initializes the random seed based on the initial seed value passed in the
  129. iInitialSeed parameter.
  130. Parameters:
  131. [IN] iInitialSeed - The initial random seed.
  132. Return value:
  133. None.
  134. --*/
  135. {
  136. //
  137. // fill in the initial seed of the random number generator
  138. //
  139. glSeed = 1664525L * iInitialSeed + 1013904223L;
  140. }
  141. static int
  142. lrand(
  143. void
  144. )
  145. /*++
  146. Purpose:
  147. This function is the equivalent of the rand() standard C library function, except that
  148. whereas rand() works only with short integers (i.e. not above 32767), this function is
  149. able to generate 32-bit random numbers.
  150. Parameters:
  151. None.
  152. Return value:
  153. The generated random number.
  154. --*/
  155. {
  156. if (glSeed == 0) // if the random seed isn't initialized...
  157. lsrand((unsigned int)time(NULL)); // initialize it first
  158. glSeed = 1664525L * glSeed + 1013904223L; // do some twisted math (infinite suite)
  159. return ((glSeed >> 1) + 1073741824L); // and return the result.
  160. }
  161. int
  162. RandomLong(
  163. int from,
  164. int to
  165. )
  166. /*++
  167. Purpose:
  168. This function returns a random integer number between (and including) the starting and
  169. ending values passed by parameters from and to.
  170. Parameters:
  171. from - the starting value.
  172. to - the ending value.
  173. Return value:
  174. The generated random number.
  175. --*/
  176. {
  177. if (to <= from)
  178. return from;
  179. return from + lrand() / (INT_MAX / (to - from + 1));
  180. }
  181. float
  182. RandomFloat(
  183. float from,
  184. float to
  185. )
  186. /*++
  187. Purpose:
  188. This function returns a random floating-point number between (and including) the starting
  189. and ending values passed by parameters from and to.
  190. Parameters:
  191. from - the starting value.
  192. to - the ending value.
  193. Return value:
  194. The generated random number.
  195. --*/
  196. {
  197. if (to <= from)
  198. return from;
  199. return from + (float)lrand() / (INT_MAX / (to - from));
  200. }
  201. void
  202. UTIL_Delay(
  203. unsigned int ms
  204. )
  205. {
  206. unsigned int t = SDL_GetTicks() + ms;
  207. while (SDL_PollEvent(NULL));
  208. while (SDL_GetTicks() < t)
  209. {
  210. SDL_Delay(1);
  211. while (SDL_PollEvent(NULL));
  212. }
  213. #ifdef PAL_HAS_NATIVEMIDI
  214. MIDI_CheckLoop();
  215. #endif
  216. }
  217. void
  218. TerminateOnError(
  219. const char *fmt,
  220. ...
  221. )
  222. // This function terminates the game because of an error and
  223. // prints the message string pointed to by fmt both in the
  224. // console and in a messagebox.
  225. {
  226. va_list argptr;
  227. char string[256];
  228. extern VOID PAL_Shutdown(VOID);
  229. // concatenate all the arguments in one string
  230. va_start(argptr, fmt);
  231. vsnprintf(string, sizeof(string), fmt, argptr);
  232. va_end(argptr);
  233. fprintf(stderr, "\nFATAL ERROR: %s\n", string);
  234. #ifdef _WIN32
  235. MessageBoxA(0, string, "FATAL ERROR", MB_ICONERROR);
  236. #endif
  237. #ifdef __linux__
  238. system(va("beep; xmessage -center \"FATAL ERROR: %s\"", string));
  239. #endif
  240. #if defined(__SYMBIAN32__)
  241. UTIL_WriteLog(LOG_DEBUG,"[0x%08x][%s][%s] - %s",(long)TerminateOnError,"TerminateOnError",__FILE__, string);
  242. SDL_Delay(3000);
  243. #endif
  244. #ifdef _DEBUG
  245. assert(!"TerminateOnError()"); // allows jumping to debugger
  246. #endif
  247. PAL_Shutdown();
  248. #if defined (NDS)
  249. while (1);
  250. #else
  251. exit(255);
  252. #endif
  253. }
  254. void *
  255. UTIL_malloc(
  256. size_t buffer_size
  257. )
  258. {
  259. // handy wrapper for operations we always forget, like checking malloc's returned pointer.
  260. void *buffer;
  261. // first off, check if buffer size is valid
  262. if (buffer_size == 0)
  263. TerminateOnError("UTIL_malloc() called with invalid buffer size: %d\n", buffer_size);
  264. buffer = malloc(buffer_size); // allocate real memory space
  265. // last check, check if malloc call succeeded
  266. if (buffer == NULL)
  267. TerminateOnError("UTIL_malloc() failure for %d bytes (out of memory?)\n", buffer_size);
  268. return buffer; // nothing went wrong, so return buffer pointer
  269. }
  270. void *
  271. UTIL_calloc(
  272. size_t n,
  273. size_t size
  274. )
  275. {
  276. // handy wrapper for operations we always forget, like checking calloc's returned pointer.
  277. void *buffer;
  278. // first off, check if buffer size is valid
  279. if (n == 0 || size == 0)
  280. TerminateOnError ("UTIL_calloc() called with invalid parameters\n");
  281. buffer = calloc(n, size); // allocate real memory space
  282. // last check, check if malloc call succeeded
  283. if (buffer == NULL)
  284. TerminateOnError("UTIL_calloc() failure for %d bytes (out of memory?)\n", size * n);
  285. return buffer; // nothing went wrong, so return buffer pointer
  286. }
  287. FILE *
  288. UTIL_OpenRequiredFile(
  289. LPCSTR lpszFileName
  290. )
  291. /*++
  292. Purpose:
  293. Open a required file. If fails, quit the program.
  294. Parameters:
  295. [IN] lpszFileName - file name to open.
  296. Return value:
  297. Pointer to the file.
  298. --*/
  299. {
  300. FILE *fp;
  301. fp = fopen(va("%s%s", PAL_PREFIX, lpszFileName), "rb");
  302. if (fp == NULL)
  303. {
  304. TerminateOnError("File not found: %s!\n", lpszFileName);
  305. }
  306. return fp;
  307. }
  308. VOID
  309. UTIL_CloseFile(
  310. FILE *fp
  311. )
  312. /*++
  313. Purpose:
  314. Close a file.
  315. Parameters:
  316. [IN] fp - file handle to be closed.
  317. Return value:
  318. None.
  319. --*/
  320. {
  321. if (fp != NULL)
  322. {
  323. fclose(fp);
  324. }
  325. }
  326. #ifdef ENABLE_LOG
  327. static FILE *pLogFile = NULL;
  328. FILE *
  329. UTIL_OpenLog(
  330. VOID
  331. )
  332. {
  333. if ((pLogFile = fopen(_PATH_LOG, "a+")) == NULL)
  334. {
  335. return NULL;
  336. }
  337. return pLogFile;
  338. }
  339. VOID
  340. UTIL_CloseLog(
  341. VOID
  342. )
  343. {
  344. if (pLogFile != NULL)
  345. {
  346. fclose(pLogFile);
  347. }
  348. }
  349. VOID
  350. UTIL_WriteLog(
  351. int Priority,
  352. const char *Fmt,
  353. ...
  354. )
  355. {
  356. va_list vaa;
  357. time_t lTime;
  358. struct tm *curTime;
  359. char szDateBuf[260];
  360. time(&lTime);
  361. if ((Priority < LOG_EMERG) || (Priority >= LOG_LAST_PRIORITY))
  362. {
  363. return;
  364. }
  365. curTime = localtime(&lTime);
  366. strftime(szDateBuf, 128, "%Y-%m-%d %H:%M:%S", curTime);
  367. szDateBuf[strlen(szDateBuf) - 1] = '\0'; //remove the
  368. va_start(vaa,Fmt);
  369. fprintf(pLogFile, "[%s]", szDateBuf);
  370. vfprintf(pLogFile, Fmt, vaa);
  371. fprintf(pLogFile, "\n");
  372. fflush(pLogFile);
  373. va_end(vaa);
  374. }
  375. #endif