y_colours_entry.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. #if defined _INC_y_colours
  2. #endinput
  3. #endif
  4. #define _INC_y_colours
  5. /*
  6. Legal:
  7. Version: MPL 1.1
  8. The contents of this file are subject to the Mozilla Public License Version
  9. 1.1 the "License"; you may not use this file except in compliance with
  10. the License. You may obtain a copy of the License at
  11. http://www.mozilla.org/MPL/
  12. Software distributed under the License is distributed on an "AS IS" basis,
  13. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. for the specific language governing rights and limitations under the
  15. License.
  16. The Original Code is the YSI framework.
  17. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  18. Portions created by the Initial Developer are Copyright C 2011
  19. the Initial Developer. All Rights Reserved.
  20. Contributors:
  21. Y_Less
  22. koolk
  23. JoeBullet/Google63
  24. g_aSlice/Slice
  25. Misiur
  26. samphunter
  27. tianmeta
  28. maddinat0r
  29. spacemud
  30. Crayder
  31. Dayvison
  32. Ahmad45123
  33. Zeex
  34. irinel1996
  35. Yiin-
  36. Chaprnks
  37. Konstantinos
  38. Masterchen09
  39. Southclaws
  40. PatchwerkQWER
  41. m0k1
  42. paulommu
  43. udan111
  44. Thanks:
  45. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  46. ZeeX - Very productive conversations.
  47. koolk - IsPlayerinAreaEx code.
  48. TheAlpha - Danish translation.
  49. breadfish - German translation.
  50. Fireburn - Dutch translation.
  51. yom - French translation.
  52. 50p - Polish translation.
  53. Zamaroht - Spanish translation.
  54. Los - Portuguese translation.
  55. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes for
  56. me to strive to better.
  57. Pixels^ - Running XScripters where the idea was born.
  58. Matite - Pestering me to release it and using it.
  59. Very special thanks to:
  60. Thiadmer - PAWN, whose limits continue to amaze me!
  61. Kye/Kalcor - SA:MP.
  62. SA:MP Team past, present and future - SA:MP.
  63. Optional plugins:
  64. Gamer_Z - GPS.
  65. Incognito - Streamer.
  66. Me - sscanf2, fixes2, Whirlpool.
  67. */
  68. #include "..\..\YSI_Core\y_utils"
  69. #include "..\..\YSI_Coding\y_stringhash"
  70. #include "..\..\YSI_Coding\y_remote"
  71. #if !defined MAX_TEXT_COLOURS
  72. #if defined MAX_TEXT_COLORS
  73. #define MAX_TEXT_COLOURS MAX_TEXT_COLORS
  74. #else
  75. #define MAX_TEXT_COLOURS (32)
  76. #endif
  77. #endif
  78. #if !defined NO_X11_COLOURS && !defined NO_X11_COLORS && !defined YSI_NO_X11
  79. #define _YSI_USE_X11 true
  80. #else
  81. #define _YSI_USE_X11 false
  82. #endif
  83. // Note that these are VERY unsafe, they're not designed for general use!
  84. #define MK_RGB(%0,%1,%2) ((%0)<<24|(%1)<<16|(%2)<<8|0xAA)
  85. #define MK_RGBA(%0,%1,%2,%3) ((%0)<<24|(%1)<<16|(%2)<<8|(%3))
  86. #define MK_D_RGB(%0,%1,%2) ((%0)<<24|(%1)<<16|(%2)<<8|0xAA)
  87. #define MK_D_RGBA(%0,%1,%2,%3) ((%0)<<24|(%1)<<16|(%2)<<8|(%3))
  88. #define MK_S_RGB(%0,%1,%2) #%0#%1#%2
  89. #define MK_S_RGBA(%0,%1,%2,%3) #%0#%1#%2
  90. #define MK_S_DEF(%0) ((%0) >>> 8)
  91. #if _YSI_USE_X11
  92. #include "y_colours_x11def"
  93. #endif
  94. #include "y_colours_gtdef"
  95. // Special macro for adding game text colours.
  96. #define GT(%0) GT_%0
  97. #define GT_~%0~ "{"#AeC01e"}{"#_GT_%0"}"
  98. // This does redefine a possible colour, but with a very obscure pattern. Also
  99. // with awkward mixed case to not match "AEC01E" or "aec01e".
  100. #define AeC01e"}{"#%0"}"~h~ AeC01e"}{"#%0h"}"
  101. // Main code start. Apparently there is a copy of the hash code in y_td.
  102. #define COLOUR_NAME_HASH(%0) YHash((%0), false, hash_bernstein, (YSI_g_sCheckSpaces) ? (-1) : (strfind((%0), " ")))
  103. #define COLOR_NAME_HASH COLOUR_NAME_HASH
  104. #if !defined X11_ALLOW_SPACES
  105. #define X11_ALLOW_SPACES (false)
  106. #endif
  107. static stock
  108. YSI_g_sColours[MAX_TEXT_COLOURS][2],
  109. bool:YSI_g_sCheckSpaces = X11_ALLOW_SPACES;
  110. remotefunc static stock void:_SetColoursCanHaveSpaces(bool:set)
  111. {
  112. YSI_g_sCheckSpaces = set;
  113. }
  114. #define SetColorsCanHaveSpaces SetColoursCanHaveSpaces
  115. stock SetColoursCanHaveSpaces(bool:set)
  116. {
  117. // Set this true/false in ALL scripts, since the text system is distributed.
  118. broadcastfunc _SetColoursCanHaveSpaces(set);
  119. //return 1;
  120. }
  121. #define SetColor SetColour
  122. stock SetColour(const name[], color)
  123. {
  124. P:3("SetColour called: \"%s\", %i", name, color);
  125. #if _YSI_USE_X11
  126. //if (name[0] | 0x20 == 'x' && name[1] == '1' && name[2] == '1')
  127. if (!strcmp(name, "X11", true, 3))
  128. {
  129. if (name[3] == ' ' || name[3] == '_')
  130. {
  131. SetColourHash(COLOUR_NAME_HASH(name[4]), color);
  132. }
  133. else
  134. {
  135. SetColourHash(COLOUR_NAME_HASH(name[3]), color);
  136. }
  137. }
  138. else
  139. #endif
  140. {
  141. SetColourHash(COLOUR_NAME_HASH(name), color);
  142. }
  143. }
  144. stock SetColourHash(hash, color)
  145. {
  146. broadcastfunc _SetColourHash(hash, color);
  147. }
  148. #define SetColorHash SetColourHash
  149. remotefunc static stock void:_SetColourHash(hash, color)
  150. {
  151. P:3("SetColourHash called: %i, %i", hash, color);
  152. color &= 0xFFFFFF00;
  153. #if _YSI_USE_X11
  154. new
  155. id = GetColourHash(hash);
  156. if (id != 0)
  157. {
  158. for (new i = 0; i != MAX_TEXT_COLOURS; ++i)
  159. {
  160. new
  161. iColor = YSI_g_sColours[i][0];
  162. if (iColor == hash)
  163. {
  164. YSI_g_sColours[i][1] = color;
  165. return; // i;
  166. }
  167. else if (iColor == 0)
  168. {
  169. // Tried to rename an X11 colour.
  170. return; // -1;
  171. }
  172. }
  173. }
  174. #endif
  175. for (new i = 0; i != MAX_TEXT_COLOURS; ++i)
  176. {
  177. new
  178. iColor = YSI_g_sColours[i][0];
  179. if (iColor == hash || iColor == 0)
  180. {
  181. YSI_g_sColours[i][0] = hash;
  182. YSI_g_sColours[i][1] = color;
  183. return; // i;
  184. }
  185. }
  186. return; // -1;
  187. }
  188. // This now uses REVERSE bernstein hash for switch compatibility.
  189. #define GetColor GetColour
  190. stock GetColour(const name[], alpha = 0xAA)
  191. {
  192. P:3("GetColour called: \"%s\", %i", name, alpha);
  193. //if (name[0] | 0x20 == 'x' && name[1] == '1' && name[2] == '2')
  194. #if _YSI_USE_X11
  195. if (!strcmp(name, "X11", true, 3))
  196. {
  197. if ((YSI_g_sCheckSpaces && name[3] == ' ') || name[3] == '_')
  198. {
  199. return GetColourHash(COLOUR_NAME_HASH(name[4]), alpha);
  200. }
  201. else
  202. {
  203. return GetColourHash(COLOUR_NAME_HASH(name[3]), alpha);
  204. }
  205. }
  206. else
  207. #endif
  208. {
  209. return GetColourHash(COLOUR_NAME_HASH(name), alpha);
  210. }
  211. }
  212. #define GetColorStream GetColourStream
  213. stock GetColourStream(const str[], &idx, alpha = 0xAA)
  214. {
  215. P:3("GetColourStream called: \"%s\", %i, %i", str, idx, alpha);
  216. // This doesn't work because the hash is backwards, not forwards. You can't
  217. // do a reverse hash incrementally. Actually you can, but not well.
  218. new
  219. pos = idx,
  220. ret = -1;
  221. #if _YSI_USE_X11
  222. //new
  223. // bool:checkSpace = YSI_g_sCheckSpaces;
  224. if (!strcmp(str[pos], "X11", true, 3))
  225. {
  226. pos += 3;
  227. if ((YSI_g_sCheckSpaces && str[pos] == ' ') || str[pos] == '_')
  228. {
  229. ++pos;
  230. }
  231. }
  232. ret = Colours_DoHashParse(str[pos], pos, YSI_g_sCheckSpaces);
  233. if (ret != -1)
  234. {
  235. idx = pos;
  236. return ret | alpha;
  237. }
  238. #endif
  239. // Do the incremental hash. This *should* be "idx = pos + 16;", but it
  240. // isn't as you shouldn't prefix custom colours with "X11" as they're not.
  241. new
  242. test = min(strlen(str[pos]), 16);
  243. while (test)
  244. {
  245. // This is a greedy test, and restricts custom text to 16 characters.
  246. ret = YHash(str[pos], false, hash_bernstein, test);
  247. for (new i = 0; i != MAX_TEXT_COLOURS; ++i)
  248. {
  249. new
  250. iColor = YSI_g_sColours[i][0];
  251. if (iColor == ret)
  252. {
  253. idx = pos + test;
  254. return alpha | YSI_g_sColours[i][1];
  255. }
  256. else if (iColor == 0)
  257. {
  258. break;
  259. }
  260. }
  261. --test;
  262. }
  263. return 0;
  264. }
  265. #define GetColorHash GetColourHash
  266. stock GetColourHash(hash, alpha = 0xAA)
  267. {
  268. P:3("GetColourHash called: %i, %i", hash, alpha);
  269. alpha &= 0xFF;
  270. // Do the REVERSE hash from YHash
  271. #pragma tabsize 4
  272. #if _YSI_USE_X11
  273. #include "y_colours_x11switch"
  274. #endif
  275. #pragma tabsize 4
  276. // Do the default code here.
  277. for (new i = 0; i != MAX_TEXT_COLOURS; ++i)
  278. {
  279. new
  280. iColor = YSI_g_sColours[i][0];
  281. if (iColor == hash)
  282. {
  283. return alpha | YSI_g_sColours[i][1];
  284. }
  285. else if (iColor == 0)
  286. {
  287. return 0;
  288. }
  289. }
  290. return 0;
  291. }
  292. #if _YSI_USE_X11
  293. static stock Colours_DoHashParse(const str[], &idx, bool:checkSpace)
  294. {
  295. // You can't use custom colours with the "#COLOR" format, but you can
  296. // with the "{COLOR}" format, this is to save on memory. It is in
  297. // theory possible to get it working with the hash format using an
  298. // incremental hash and compare. NOW SUPPORTED!
  299. #include "y_colours_x11parse"
  300. #pragma tabsize 4
  301. return -1;
  302. }
  303. #endif
  304. #define _COLOUR_GT_SPACE_DEF_0(%0) SAMP_GAME_TEXT_%0
  305. #define _COLOUR_GT_SPACE_DEF_1(%0) SAMP_GAME_TEXT_%0H
  306. #define _COLOUR_GT_SPACE_DEF_2(%0) SAMP_GAME_TEXT_%0HH
  307. #define _COLOUR_GT_SPACE_DEF_3(%0) SAMP_GAME_TEXT_%0HHH
  308. #define _COLOUR_GT_SPACE_DEF_4(%0) SAMP_GAME_TEXT_%0HHHH
  309. #define _COLOUR_GT_SPACE_DEF_5(%0) SAMP_GAME_TEXT_%0HHHHH
  310. #define _COLOUR_GT_SPACE(%0,%1) {('%0'|0x20)|(%1<<8),_COLOUR_GT_SPACE_DEF_%1(%0)>>>24,_COLOUR_GT_SPACE_DEF_%1(%0)>>16&0xFF,_COLOUR_GT_SPACE_DEF_%1(%0)>>8&0xFF}
  311. #define Colors_SAMPToGT Colours_SAMPToGT
  312. stock Colours_SAMPToGT(colour, start)
  313. {
  314. P:4("Colours_SAMPToGT called: %i", colour);
  315. // Find the closest matching game text colour to the given SA:MP colour.
  316. static const
  317. sc_aColours[][4] =
  318. {
  319. // These can't be used as you can't set text to them. You can
  320. // however use them at the start by not changing.
  321. _COLOUR_GT_SPACE(X,0), _COLOUR_GT_SPACE(X,1),
  322. _COLOUR_GT_SPACE(X,2),
  323. _COLOUR_GT_SPACE(R,0), _COLOUR_GT_SPACE(R,1),
  324. _COLOUR_GT_SPACE(R,2), _COLOUR_GT_SPACE(R,3),
  325. _COLOUR_GT_SPACE(R,4), _COLOUR_GT_SPACE(R,5),
  326. _COLOUR_GT_SPACE(G,0), _COLOUR_GT_SPACE(G,1),
  327. _COLOUR_GT_SPACE(G,2), _COLOUR_GT_SPACE(G,3),
  328. //_COLOUR_GT_SPACE(G,4), // Don't want this twice (see Y2).
  329. _COLOUR_GT_SPACE(B,0), _COLOUR_GT_SPACE(B,1),
  330. _COLOUR_GT_SPACE(B,2), _COLOUR_GT_SPACE(B,3),
  331. _COLOUR_GT_SPACE(Y,0), _COLOUR_GT_SPACE(Y,1),
  332. _COLOUR_GT_SPACE(Y,2),
  333. _COLOUR_GT_SPACE(P,0), _COLOUR_GT_SPACE(P,1),
  334. _COLOUR_GT_SPACE(P,2),
  335. _COLOUR_GT_SPACE(W,0),
  336. _COLOUR_GT_SPACE(L,0)
  337. };
  338. new
  339. dist = cellmax,
  340. found = '\0',
  341. r = colour >> 16,
  342. g = (colour >> 8) & 0xFF,
  343. b = colour & 0xFF,
  344. tr, tg, tb, cur;
  345. for ( ; start != sizeof (sc_aColours); ++start)
  346. {
  347. tr = r - sc_aColours[start][1],
  348. tg = g - sc_aColours[start][2],
  349. tb = b - sc_aColours[start][3],
  350. cur = (tr * tr) + (tg * tg) + (tb * tb);
  351. P:6("Colours_SAMPToGT: Test %x %d", sc_aColours[start][0], cur);
  352. if (cur < dist)
  353. {
  354. P:6("Colours_SAMPToGT: Change %x %d", found, dist);
  355. // This may sometimes give odd results in fades for draw results.
  356. // Though I've not seen it happen yet.
  357. dist = cur,
  358. found = sc_aColours[start][0];
  359. }
  360. }
  361. return found;
  362. }
  363. stock Colours_EncodeGameText(str[])
  364. {
  365. new
  366. ret;
  367. if (str[0] == '~')
  368. {
  369. switch (str[1] | 0x20)
  370. {
  371. case 'r', 'g', 'b', 'y', 'p', 'w', 'l', 'x':
  372. {
  373. ret = str[1] | 0x20;
  374. }
  375. case 'h':
  376. {
  377. ret = 0x100 | 'x';
  378. }
  379. default: return 0;
  380. }
  381. if (str[2] != '~') return 0;
  382. new
  383. pos = 3;
  384. while (str[pos++] == '~' && str[pos++] | 0x20 == 'h' && str[pos++] == '~')
  385. {
  386. ret += 0x100;
  387. }
  388. }
  389. return ret;
  390. }