Clone of PhatAC @ https://github.com/floaterxk/PhatAC

Util.cpp 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. #include "StdAfx.h"
  2. #include "TurbineFormats.h"
  3. bool LoadDataFromFile(const char *filepath, BYTE **data, DWORD *length)
  4. {
  5. *data = NULL;
  6. *length = 0;
  7. FILE *fp = fopen(filepath, "rb");
  8. if (fp)
  9. {
  10. fseek(fp, 0, SEEK_END);
  11. long _fileSize = ftell(fp);
  12. fseek(fp, 0, SEEK_SET);
  13. if (_fileSize < 0)
  14. _fileSize = 0;
  15. DWORD fileSize = (DWORD)_fileSize;
  16. BYTE *fileData = new BYTE[fileSize];
  17. fread(fileData, fileSize, 1, fp);
  18. fclose(fp);
  19. *data = fileData;
  20. *length = fileSize;
  21. return true;
  22. }
  23. return false;
  24. }
  25. static char szReadBuffer[1024];
  26. static char szWriteBuffer[600];
  27. char* csprintf(const char *format, ...)
  28. {
  29. szReadBuffer[0] = 0;
  30. va_list args;
  31. va_start(args, format);
  32. _vsnprintf(szReadBuffer, 1024, format, args);
  33. va_end(args);
  34. szReadBuffer[1023] = '\0';
  35. return szReadBuffer;
  36. }
  37. char *timestamp()
  38. {
  39. static char result[16];
  40. tm *beef;
  41. time_t cake;
  42. time(&cake);
  43. beef = localtime(&cake);
  44. if (beef)
  45. sprintf(result, "%.2d:%.2d:%.2d", beef->tm_hour, beef->tm_min, beef->tm_sec);
  46. else
  47. result[0] = 0;
  48. return result;
  49. }
  50. unsigned long ResolveIPFromHost(const char *host)
  51. {
  52. ULONG ipaddr;
  53. // Check if it's in IP format.
  54. ipaddr = ::inet_addr(host);
  55. if (ipaddr && ipaddr != INADDR_NONE)
  56. return (unsigned long)ipaddr;
  57. // Try to resolve an IP address.
  58. LPHOSTENT lphost;
  59. lphost = gethostbyname(host);
  60. if (lphost != NULL)
  61. {
  62. ipaddr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  63. if (ipaddr && ipaddr != INADDR_NONE)
  64. return (unsigned long)ipaddr;
  65. }
  66. return 0;
  67. }
  68. unsigned long GetLocalIP()
  69. {
  70. char hostname[256];
  71. gethostname(hostname, 256);
  72. DWORD hostaddr = *((DWORD *)gethostbyname(hostname)->h_addr);
  73. return *(unsigned long *)gethostbyname(hostname)->h_addr;
  74. }
  75. std::string GetLocalIPString()
  76. {
  77. unsigned long localIP = GetLocalIP();
  78. return inet_ntoa(*(in_addr *)&localIP);
  79. }
  80. std::string DebugBytesToString(void *_data, unsigned int len)
  81. {
  82. BYTE *data = (BYTE *)_data;
  83. std::string strBytes;
  84. for (unsigned int i = 0; i < len; i++)
  85. {
  86. char temp[3];
  87. sprintf(temp, "%02X", data[i]);
  88. strBytes += temp;
  89. if (!((i + 1) % 16))
  90. strBytes += "\n";
  91. else
  92. strBytes += " ";
  93. }
  94. if (len % 16)
  95. {
  96. strBytes += "\n";
  97. }
  98. return strBytes;
  99. }
  100. void MsgBox(UINT type, const char *format, ...)
  101. {
  102. szWriteBuffer[0] = 0;
  103. va_list args;
  104. va_start(args, format);
  105. _vsnprintf(szWriteBuffer, 1024, format, args);
  106. va_end(args);
  107. HWND hWnd = g_pGlobals ? g_pGlobals->GetWindowHandle() : NULL;
  108. MessageBox(hWnd, szWriteBuffer, "PhatAC", MB_OK | type);
  109. }
  110. void MsgBox(const char *format, ...)
  111. {
  112. szWriteBuffer[0] = 0;
  113. va_list args;
  114. va_start(args, format);
  115. _vsnprintf(szWriteBuffer, 1024, format, args);
  116. va_end(args);
  117. MessageBox(NULL, szWriteBuffer, "PhatAC", MB_OK);
  118. }
  119. void MsgBoxError(DWORD dwError, const char* event)
  120. {
  121. LPVOID lpMsgBuf;
  122. if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  123. FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  124. NULL,
  125. GetLastError(),
  126. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  127. (LPTSTR)&lpMsgBuf,
  128. 0, NULL))
  129. {
  130. MsgBox(MB_ICONHAND, "Unknown error #%lu %s", dwError, event);
  131. return;
  132. }
  133. MsgBox(MB_ICONHAND, "Error #%lu %s:\r\n%s", dwError, event, lpMsgBuf);
  134. LocalFree(lpMsgBuf);
  135. }
  136. #define REGLOC HKEY_LOCAL_MACHINE, "Software\\PhatAC"
  137. BOOL SaveConfigKey(const char* Key, DWORD value)
  138. {
  139. BOOL bReturn = FALSE;
  140. HKEY hKey;
  141. if (RegCreateKeyEx(REGLOC, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
  142. {
  143. if (SUCCEEDED(RegSetValueEx(hKey, Key, NULL, REG_DWORD, (BYTE *)&value, sizeof(DWORD))))
  144. bReturn = TRUE;
  145. RegCloseKey(hKey);
  146. }
  147. return bReturn;
  148. }
  149. BOOL SaveConfigKey(const char* Key, const char* value)
  150. {
  151. BOOL bReturn = FALSE;
  152. HKEY hKey;
  153. if (RegCreateKeyEx(REGLOC, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
  154. {
  155. if (SUCCEEDED(RegSetValueEx(hKey, Key, NULL, REG_SZ, (BYTE*)value, (DWORD)strlen(value) + 1)))
  156. bReturn = TRUE;
  157. RegCloseKey(hKey);
  158. }
  159. return bReturn;
  160. }
  161. BOOL ReadConfigKey(const char* Key, DWORD* value)
  162. {
  163. DWORD type = REG_DWORD;
  164. DWORD size = sizeof(DWORD);
  165. BOOL bReturn = FALSE;
  166. HKEY hKey;
  167. if (RegOpenKeyEx(REGLOC, NULL, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
  168. {
  169. if (!RegQueryValueEx(hKey, Key, NULL, &type, (BYTE*)value, &size))
  170. bReturn = TRUE;
  171. RegCloseKey(hKey);
  172. }
  173. return bReturn;
  174. }
  175. BOOL ReadConfigKey(const char* Key, char* value, DWORD size)
  176. {
  177. DWORD type = REG_SZ;
  178. BOOL bReturn = FALSE;
  179. HKEY hKey;
  180. if (RegOpenKeyEx(REGLOC, NULL, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
  181. {
  182. if (!RegQueryValueEx(hKey, Key, NULL, &type, (BYTE*)value, &size))
  183. bReturn = TRUE;
  184. RegCloseKey(hKey);
  185. }
  186. return bReturn;
  187. }
  188. bool FileExists(const char *filePath)
  189. {
  190. DWORD dwAttrib = GetFileAttributes(filePath);
  191. return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
  192. }
  193. void strtrim(char *szText)
  194. {
  195. //how many left spaces are leading?
  196. int leading = 0;
  197. while (szText[leading] == ' ')
  198. leading++;
  199. if (leading) { //shift left
  200. int i = leading;
  201. while (1)
  202. {
  203. szText[i - leading] = szText[i];
  204. if (szText[i] == 0)
  205. break;
  206. i++;
  207. }
  208. }
  209. int pos = (int)strlen(szText) - 1; //remove trailing spaces
  210. while ((pos >= 0) && szText[pos] == ' ')
  211. szText[pos--] = 0;
  212. }
  213. BOOL strmask(const char* szTest, const char* szMask)
  214. {
  215. //We need to someday create a function for validating a string mask.
  216. return FALSE;
  217. }
  218. long fsize(FILE* fileptr)
  219. {
  220. long lOld, lSize;
  221. lOld = ftell(fileptr);
  222. fseek(fileptr, 0, SEEK_END);
  223. lSize = ftell(fileptr);
  224. fseek(fileptr, lOld, SEEK_SET);
  225. return lSize;
  226. }
  227. float NorthSouth(char *szCoord)
  228. {
  229. strlwr(szCoord);
  230. strtrim(szCoord);
  231. int len = (int)strlen(szCoord);
  232. if (len < 1)
  233. return 0;
  234. char *end = &szCoord[len - 1];
  235. char NS = *end;
  236. *end = 0;
  237. strtrim(szCoord);
  238. float dir = 0.0f;
  239. if (NS == 'n')
  240. dir = 1.0f;
  241. else if (NS == 's')
  242. dir = -1.0f;
  243. float coord = 0.0f;
  244. sscanf(szCoord, "%f", &coord);
  245. return coord * dir;
  246. }
  247. float EastWest(char *szCoord)
  248. {
  249. strlwr(szCoord);
  250. strtrim(szCoord);
  251. int len = (int)strlen(szCoord);
  252. if (len < 1)
  253. return 0;
  254. char *end = &szCoord[len - 1];
  255. char EW = *end;
  256. *end = 0;
  257. strtrim(szCoord);
  258. float dir = 0.0f;
  259. if (EW == 'e')
  260. dir = 1.0f;
  261. else if (EW == 'w')
  262. dir = -1.0f;
  263. float coord = 0.0f;
  264. sscanf(szCoord, "%f", &coord);
  265. return coord * dir;
  266. }
  267. DWORD GetCellFromBase(DWORD BaseX, DWORD BaseY)
  268. {
  269. BYTE blockx = (BYTE)(BaseX >> 3);
  270. BYTE blocky = (BYTE)(BaseY >> 3);
  271. BYTE cellx = (BYTE)(BaseX & 7);
  272. BYTE celly = (BYTE)(BaseY & 7);
  273. WORD block = (blockx << 8) | (blocky);
  274. WORD cell = (cellx << 3) | (celly);
  275. DWORD dwCell = (block << 16) | (cell + 1);
  276. return dwCell;
  277. }
  278. loc_t GetLocation(double NS, double EW)
  279. {
  280. NS -= 0.5f;
  281. EW -= 0.5f;
  282. NS *= 10.0f;
  283. EW *= 10.0f;
  284. DWORD basex = (DWORD)(EW + 0x400);
  285. DWORD basey = (DWORD)(NS + 0x400);
  286. if (long(basex) < 0 || long(basey) < 0 || basex >= 0x7F8 || basey >= 0x7F8)
  287. {
  288. //Out of bounds.
  289. return loc_t();
  290. }
  291. DWORD dwCell = GetCellFromBase(basex, basey);
  292. float xOffset = ((basex & 7) * 24.0f) + 12;
  293. float yOffset = ((basey & 7) * 24.0f) + 12;
  294. loc_t Result;
  295. Result.landcell = dwCell;
  296. Result.x = xOffset;
  297. Result.y = yOffset;
  298. Result.z = CalcSurfaceZ(dwCell, xOffset, yOffset);
  299. return Result;
  300. }
  301. // Water blocks are not passable!
  302. BOOL IsWaterBlock(BlockData *pBlock)
  303. {
  304. for (unsigned int x = 0; x < 9; x++) {
  305. for (unsigned int y = 0; y < 9; y++) {
  306. if ((pBlock->wSurface[x][y] & 0x50) != 0x50)
  307. return FALSE;
  308. }
  309. }
  310. return TRUE;
  311. }
  312. //
  313. BOOL IsWaterBlock(DWORD dwCell)
  314. {
  315. dwCell &= 0xFFFF0000;
  316. dwCell |= 0x0000FFFF;
  317. TURBINEFILE *pFile = g_pCell->GetFile(dwCell);
  318. if (!pFile)
  319. return FALSE;
  320. BOOL bResult = IsWaterBlock((BlockData*)pFile->GetData());
  321. delete pFile;
  322. return bResult;
  323. }
  324. BOOL HasObjectBlock(BlockData *pBlock)
  325. {
  326. return ((pBlock->bObject) ? TRUE : FALSE);
  327. }
  328. BOOL HasObjectBlock(DWORD dwCell)
  329. {
  330. dwCell &= 0xFFFF0000;
  331. dwCell |= 0x0000FFFF;
  332. TURBINEFILE *pFile = g_pCell->GetFile(dwCell);
  333. if (!pFile)
  334. return FALSE;
  335. BOOL bResult = HasObjectBlock((BlockData*)pFile->GetData());
  336. delete pFile;
  337. return bResult;
  338. }
  339. float CalcSurfaceZ(DWORD dwCell, float xOffset, float yOffset)
  340. {
  341. TURBINEFILE *pFile = g_pCell->GetFile((dwCell & 0xFFFF0000) | 0xFFFF);
  342. if (!pFile)
  343. return 0;
  344. WORD cell = CELL_WORD(dwCell);
  345. int minix = (cell >> 3) & 7;
  346. int miniy = (cell >> 0) & 7;
  347. xOffset -= (24 * minix);
  348. yOffset -= (24 * miniy);
  349. BlockData *pBlock = (BlockData*)pFile->GetData();
  350. Vector P1(0, 24, pBlock->bHeight[minix][miniy + 1] * 2.0f);
  351. Vector P2;
  352. Vector P3(24, 0, pBlock->bHeight[minix + 1][miniy] * 2.0f);
  353. if ((xOffset + yOffset) < 1.0f)
  354. P2 = Vector(0, 0, pBlock->bHeight[minix][miniy] * 2.0f);
  355. else
  356. P2 = Vector(24, 24, pBlock->bHeight[minix + 1][miniy + 1] * 2.0f);
  357. delete pFile;
  358. return FindVectorZ(P1, P2, P3, xOffset, yOffset);
  359. }