y_formatin.inc 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329
  1. /**--------------------------------------------------------------------------**\
  2. ==========================
  3. y_colours - X11 colours!
  4. ==========================
  5. Description:
  6. This holds the colour information that used to be part of the text system
  7. but which is far more useful than just for text. This now supports the full
  8. set of X11 colours, both by name and by definition. You can also define
  9. your own if you so choose (up to 32 - should be enough given that this
  10. includes the X11 colours).
  11. Legal:
  12. Version: MPL 1.1
  13. The contents of this file are subject to the Mozilla Public License Version
  14. 1.1 (the "License"); you may not use this file except in compliance with
  15. the License. You may obtain a copy of the License at
  16. http://www.mozilla.org/MPL/
  17. Software distributed under the License is distributed on an "AS IS" basis,
  18. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  19. for the specific language governing rights and limitations under the
  20. License.
  21. The Original Code is the YSI format include.
  22. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  23. Portions created by the Initial Developer are Copyright (C) 2011
  24. the Initial Developer. All Rights Reserved.
  25. Contributors:
  26. ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
  27. Thanks:
  28. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  29. ZeeX - Very productive conversations.
  30. koolk - IsPlayerinAreaEx code.
  31. TheAlpha - Danish translation.
  32. breadfish - German translation.
  33. Fireburn - Dutch translation.
  34. yom - French translation.
  35. 50p - Polish translation.
  36. Zamaroht - Spanish translation.
  37. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
  38. for me to strive to better.
  39. Pixels^ - Running XScripters where the idea was born.
  40. Matite - Pestering me to release it and using it.
  41. Very special thanks to:
  42. Thiadmer - PAWN, whose limits continue to amaze me!
  43. Kye/Kalcor - SA:MP.
  44. SA:MP Team past, present and future - SA:MP.
  45. Version:
  46. 1.0
  47. Changelog:
  48. 29/11/10:
  49. Added the ability to use "X11" prefixes in strings.
  50. Added colourspace resolution for converting {FF0000} to ~r~.
  51. 25/11/10:
  52. First version.
  53. </remarks>
  54. \**--------------------------------------------------------------------------**/
  55. #include <a_samp>
  56. #include "..\y_debug"
  57. #include "..\y_colours"
  58. // Custom specifier data.
  59. #define F@k<%0>(%1) F@k%0(%1)
  60. #if defined FORMAT_CUSTOM_SPEC_BUFFER_SIZE
  61. // Sorry, no can do.
  62. #undef FORMAT_CUSTOM_SPEC_BUFFER_SIZE
  63. #endif
  64. // =====================================================================
  65. // UPDATE Y_RENDER_FIX_NEGATIVE MACRO ON CHANGE!!!!!!!
  66. #define FORMAT_CUSTOM_SPEC_BUFFER_SIZE 130
  67. // Also "ts" in y_textrender.
  68. // =====================================================================
  69. // This is NOT QUITE compatible with Slice's version. I had to modify the
  70. // "FMAT@2" macro to better support extended parameter options (width etc).
  71. #define FormatSpecifier<'%1'>(%2[%3],%4) FMAT@1:F@%1(%2[FORMAT_CUSTOM_SPEC_BUFFER_SIZE],FMAT@2:___unused,%4)
  72. #if defined FMAT@2
  73. #undef FMAT@2
  74. #endif
  75. #define FMAT@2:___unused,%1[%2]%3) %1[%2],__unused%3)
  76. #define FMAT@1:%1(%2) forward %1(%2); public %1(%2)
  77. #define FORMAT_FLAG_LEFT (_:e_COMPRESS_FORMAT_DATA_LEFT)
  78. #define FORMAT_FLAG_ZERO (_:e_COMPRESS_FORMAT_DATA_ZERO)
  79. #define FORMAT:%0(%1) FormatSpecifier<'%0'>(%1)
  80. // Enumeration for the possible keys they can want.
  81. enum e_GAME_TEXT_KEYS
  82. {
  83. e_NO_KEY_SELECTED,
  84. e_PED_ANSWER_PHONE,
  85. e_PED_DUCK,
  86. e_PED_FIREWEAPON,
  87. e_PED_FIREWEAPON_ALT,
  88. e_PED_SPRINT,
  89. e_VEHICLE_ENTER_EXIT,
  90. e_PED_JUMPING,
  91. e_PED_LOCK_TARGET,
  92. e_PED_LOOKBEHIND,
  93. e_SNEAK_ABOUT,
  94. e_VEHICLE_LOOKLEFT,
  95. e_VEHICLE_LOOKRIGHT,
  96. e_GO_FORWARD,
  97. e_GO_BACK,
  98. e_GO_LEFT,
  99. e_GO_RIGHT,
  100. e_VEHICLE_FIREWEAPON,
  101. e_VEHICLE_HORN,
  102. e_VEHICLE_FIREWEAPON_ALT,
  103. e_VEHICLE_ACCELERATE,
  104. e_VEHICLE_BRAKE,
  105. e_VEHICLE_HANDBRAKE,
  106. e_VEHICLE_SUBMISSIONS,
  107. e_VEHICLE_LOOKBEHIND,
  108. e_VEHICLE_TURRETUP,
  109. e_VEHICLE_TURRETDOWN,
  110. e_VEHICLE_TURRETLEFT,
  111. e_VEHICLE_TURRETRIGHT,
  112. e_VEHICLE_STEERUP,
  113. e_VEHICLE_STEERDOWN,
  114. e_VEHICLE_STEERLEFT,
  115. e_VEHICLE_STEERRIGHT
  116. }
  117. // Can support up to 16 specifier types, more requires a rewrite, unfortunately
  118. // there are currently 15, though I can't think of any more...
  119. enum e_COMPRESS_FORMAT_DATA (+= 0x10000000)
  120. {
  121. e_COMPRESS_FORMAT_DATA_WIDTH = 0x00000FFF, // 0x800 = *, 0 = none,
  122. e_COMPRESS_FORMAT_DATA_PREC = 0x00FFF000, // 0xFFF = default
  123. e_COMPRESS_FORMAT_DATA_LEFT = 0x01000000,
  124. e_COMPRESS_FORMAT_DATA_ZERO = 0x02000000,
  125. e_COMPRESS_FORMAT_DATA_LIST = 0x04000000, // Array of data
  126. e_COMPRESS_FORMAT_DATA_FUNC = 0x08000000, // Function of data
  127. e_COMPRESS_FORMAT_DATA_TYPE = 0xF0000000,
  128. e_COMPRESS_FORMAT_DATA_DEC = 0x10000000, // Decimal : d, i
  129. e_COMPRESS_FORMAT_DATA_HEX, // Hex : h, x
  130. e_COMPRESS_FORMAT_DATA_BIN, // Binary : b
  131. e_COMPRESS_FORMAT_DATA_CHAR, // Character : c
  132. e_COMPRESS_FORMAT_DATA_FLOAT, // Float : f
  133. e_COMPRESS_FORMAT_DATA_IEEE, // IEEE : g
  134. e_COMPRESS_FORMAT_DATA_STRING, // String : s
  135. e_COMPRESS_FORMAT_DATA_OCT, // Octal : o
  136. e_COMPRESS_FORMAT_DATA_COMM, // Command : n
  137. e_COMPRESS_FORMAT_DATA_SUFFIX, // Suffix : p
  138. e_COMPRESS_FORMAT_DATA_UNSIGNED, // Unsigned : u
  139. e_COMPRESS_FORMAT_DATA_SIGNED, // Signed : t
  140. e_COMPRESS_FORMAT_DATA_PLAYER, // Player : q
  141. e_COMPRESS_FORMAT_DATA_LOGICAL, // Logical : l
  142. // TODO: Make "custom" ala Slice's formatex.
  143. //e_COMPRESS_FORMAT_DATA_DATE // Date : DATE
  144. e_COMPRESS_FORMAT_DATA_CUSTOM
  145. }
  146. #define Y_FORMAT_GT_LIGHTER (0x10000000)
  147. #define Y_FORMAT_CLOSE_CURR (0x20000000)
  148. #define Y_FORMAT_START_FADE (0x40000000)
  149. #define Y_FORMAT_ALWAYS_SET (0x80000000)
  150. #define Y_FORMAT_IS_INSERT ('\02')
  151. #define Y_FORMAT_IS_COLOUR ('\03')
  152. #define Y_FORMAT_IS_KEY ('\04')
  153. #define Y_COLOURS_CASE(%0:%1) case '%0':return ++iIn,ret|e_COMPRESS_FORMAT_DATA_%1|(e_COMPRESS_FORMAT_DATA:((width&0xFFF)|((prec&0xFFF)<<12)))
  154. #define Y_ESCAPES_CASE(%0:%1) case '%0':(iOut+1<len)&&(output[iOut++]='%1'),++iIn
  155. #define Y_FORMAT_STRING_SKIP(); //if(iOut+1<len)output[iOut]=0,lastChar=iOut++
  156. /**--------------------------------------------------------------------------**\
  157. <summary>Format_GetKeys</summary>
  158. <param name="const input[]">String to read from.</param>
  159. <param name="&idx">Current read index.</param>
  160. <returns>
  161. e_GAME_TEXT_KEYS - Enum representation of keys.
  162. </returns>
  163. <remarks>
  164. Reads a GameText key identifier and compresses it essentially.
  165. </remarks>
  166. \**--------------------------------------------------------------------------**/
  167. stock e_GAME_TEXT_KEYS:Format_GetKeys(const input[], &idx)
  168. {
  169. P:3("e_GAME_TEXT_KEYS:Format_GetKeys called: \"%s\", %i", input, idx);
  170. if (input[idx] != '~')
  171. {
  172. return e_NO_KEY_SELECTED;
  173. }
  174. if (input[++idx])
  175. {
  176. if (!strcmp(input[idx], !"PED_ANSWER_PHONE~", true, 17))
  177. {
  178. idx += 17;
  179. return e_PED_ANSWER_PHONE;
  180. }
  181. else if (!strcmp(input[idx], !"PED_DUCK~", true, 9))
  182. {
  183. idx += 9;
  184. return e_PED_DUCK;
  185. }
  186. else if (!strcmp(input[idx], !"PED_FIREWEAPON~", true, 15))
  187. {
  188. idx += 15;
  189. return e_PED_FIREWEAPON;
  190. }
  191. else if (!strcmp(input[idx], !"PED_FIREWEAPON_ALT~", true, 29))
  192. {
  193. idx += 29;
  194. return e_PED_FIREWEAPON_ALT;
  195. }
  196. else if (!strcmp(input[idx], !"PED_SPRINT~", true, 11))
  197. {
  198. idx += 11;
  199. return e_PED_SPRINT;
  200. }
  201. else if (!strcmp(input[idx], !"VEHICLE_ENTER_EXIT~", true, 19))
  202. {
  203. idx += 19;
  204. return e_VEHICLE_ENTER_EXIT;
  205. }
  206. else if (!strcmp(input[idx], !"PED_JUMPING~", true, 12))
  207. {
  208. idx += 12;
  209. return e_PED_JUMPING;
  210. }
  211. else if (!strcmp(input[idx], !"PED_LOCK_TARGET~", true, 16))
  212. {
  213. idx += 16;
  214. return e_PED_LOCK_TARGET;
  215. }
  216. else if (!strcmp(input[idx], !"PED_LOOKBEHIND~", true, 15))
  217. {
  218. idx += 15;
  219. return e_PED_LOOKBEHIND;
  220. }
  221. else if (!strcmp(input[idx], !"SNEAK_ABOUT~", true, 12))
  222. {
  223. idx += 12;
  224. return e_SNEAK_ABOUT;
  225. }
  226. else if (!strcmp(input[idx], !"VEHICLE_LOOKLEFT~", true, 17))
  227. {
  228. idx += 17;
  229. return e_VEHICLE_LOOKLEFT;
  230. }
  231. else if (!strcmp(input[idx], !"VEHICLE_LOOKRIGHT~", true, 18))
  232. {
  233. idx += 18;
  234. return e_VEHICLE_LOOKRIGHT;
  235. }
  236. else if (!strcmp(input[idx], !"GO_FORWARD~", true, 11))
  237. {
  238. idx += 11;
  239. return e_GO_FORWARD;
  240. }
  241. else if (!strcmp(input[idx], !"GO_BACK~", true, 8))
  242. {
  243. idx += 8;
  244. return e_GO_BACK;
  245. }
  246. else if (!strcmp(input[idx], !"GO_LEFT~", true, 8))
  247. {
  248. idx += 8;
  249. return e_GO_LEFT;
  250. }
  251. else if (!strcmp(input[idx], !"GO_RIGHT~", true, 9))
  252. {
  253. idx += 9;
  254. return e_GO_RIGHT;
  255. }
  256. else if (!strcmp(input[idx], !"VEHICLE_FIREWEAPON~", true, 19))
  257. {
  258. idx += 19;
  259. return e_VEHICLE_FIREWEAPON;
  260. }
  261. else if (!strcmp(input[idx], !"VEHICLE_HORN~", true, 13))
  262. {
  263. idx += 13;
  264. return e_VEHICLE_HORN;
  265. }
  266. else if (!strcmp(input[idx], !"VEHICLE_FIREWEAPON_ALT~", true, 23))
  267. {
  268. idx += 23;
  269. return e_VEHICLE_FIREWEAPON_ALT;
  270. }
  271. else if (!strcmp(input[idx], !"VEHICLE_ACCELERATE~", true, 19))
  272. {
  273. idx += 19;
  274. return e_VEHICLE_ACCELERATE;
  275. }
  276. else if (!strcmp(input[idx], !"VEHICLE_BRAKE~", true, 14))
  277. {
  278. idx += 14;
  279. return e_VEHICLE_BRAKE;
  280. }
  281. else if (!strcmp(input[idx], !"VEHICLE_HANDBRAKE~", true, 18))
  282. {
  283. idx += 18;
  284. return e_VEHICLE_HANDBRAKE;
  285. }
  286. else if (!strcmp(input[idx], !"VEHICLE_SUBMISSIONS~", true, 20))
  287. {
  288. idx += 20;
  289. return e_VEHICLE_SUBMISSIONS;
  290. }
  291. else if (!strcmp(input[idx], !"VEHICLE_LOOKBEHIND~" , true, 19))
  292. {
  293. idx += 19;
  294. return e_VEHICLE_LOOKBEHIND;
  295. }
  296. else if (!strcmp(input[idx], !"VEHICLE_TURRETUP~", true, 17))
  297. {
  298. idx += 17;
  299. return e_VEHICLE_TURRETUP;
  300. }
  301. else if (!strcmp(input[idx], !"VEHICLE_TURRETDOWN~", true, 19))
  302. {
  303. idx += 19;
  304. return e_VEHICLE_TURRETDOWN;
  305. }
  306. else if (!strcmp(input[idx], !"VEHICLE_TURRETLEFT~", true, 19))
  307. {
  308. idx += 19;
  309. return e_VEHICLE_TURRETLEFT;
  310. }
  311. else if (!strcmp(input[idx], !"VEHICLE_TURRETRIGHT~", true, 20))
  312. {
  313. idx += 20;
  314. return e_VEHICLE_TURRETRIGHT;
  315. }
  316. else if (!strcmp(input[idx], !"VEHICLE_STEERUP~", true, 16))
  317. {
  318. idx += 16;
  319. return e_VEHICLE_STEERUP;
  320. }
  321. else if (!strcmp(input[idx], !"VEHICLE_STEERDOWN~", true, 18))
  322. {
  323. idx += 18;
  324. return e_VEHICLE_STEERDOWN;
  325. }
  326. else if (!strcmp(input[idx], !"VEHICLE_STEERLEFT~", true, 18))
  327. {
  328. idx += 18;
  329. return e_VEHICLE_STEERLEFT;
  330. }
  331. else if (!strcmp(input[idx], !"VEHICLE_STEERRIGHT~", true, 19))
  332. {
  333. idx += 19;
  334. return e_VEHICLE_STEERRIGHT;
  335. }
  336. }
  337. return e_NO_KEY_SELECTED;
  338. }
  339. /**--------------------------------------------------------------------------**\
  340. <summary>Format_Standardise</summary>
  341. <param name="input[]">The text to read in.</param>
  342. <param name="output[]">The destination array. Can be the same as "input".</param>
  343. <param name="len">The length of the output array.</param>
  344. <param name="pt - Special mode for parsing player text">has "()" but no "%" or keys.</param>
  345. <returns>
  346. The length of the string.
  347. </returns>
  348. <remarks>
  349. Takes a string input and converts it to a standardised representation, i.e.
  350. uses byte-codes instead of human readable codes to represent formats and
  351. colours. This makes it faster to format in to any other representation,
  352. instead of having to convert between all possible combinations, we just have
  353. this to convert basically all formats at once (it can handle hybrids of all
  354. the different representations) to a single fast read format and then have
  355. fairly simple to write methods to convert that single format to any other
  356. format (see y_formatout.inc).
  357. </remarks>
  358. \**--------------------------------------------------------------------------**/
  359. stock Format_Standardise(input[], output[], len = sizeof (output), pt = false)
  360. {
  361. P:2("Format_Standardise called: %s, %d, %d", input, len, pt);
  362. new
  363. ch,
  364. iIn = 0,
  365. iOut = 0, //1,
  366. bool:fade = false,
  367. colour,
  368. tmp,
  369. steps;//,
  370. //lastChar = 0;
  371. // Adjust len so we know we can fit the NULL.
  372. --len;
  373. while ((ch = input[iIn]))
  374. {
  375. // Update where the next element of interest is.
  376. //output[lastChar] = iOut;
  377. // This is now ALWAYS candelled by the next colour to be found, but the
  378. // {<COLOUR} syntax is still supported. The reason is that I got
  379. // annoyed by that syntax almost instantly.
  380. fade = false;
  381. colour = -1;
  382. P:7("Format_Standardise: loop pt 1 %c %d %d", ch, iIn, iOut);
  383. switch (ch)
  384. {
  385. case '#':
  386. {
  387. // Hash colours introduced by RyDeR`.
  388. /*if (fade)
  389. {
  390. fade = false;
  391. }*/
  392. if (input[++iIn] == '\0')
  393. {
  394. continue;
  395. }
  396. // Try and find the named colour.
  397. #if _YSI_USE_X11
  398. if (!strcmp(input[iIn], "X11", true, 3))
  399. {
  400. iIn += 3;
  401. if (input[iIn] == ' ' || input[iIn] == '_')
  402. {
  403. ++iIn;
  404. }
  405. }
  406. // This can't do custom colours as there's no way to tell
  407. // where they end.
  408. colour = GetColourStream(input, iIn); //Colours_DoHashParse(input[iIn], iIn);
  409. //return Colours_DoHashParse(input, idx);
  410. if (colour != 0)
  411. {
  412. colour >>>= 8;
  413. goto Format_Standardise_no_switch;
  414. }
  415. #endif
  416. // Need to accept 3 and 6 character hex codes.
  417. colour = 0;
  418. //idx = iIn;
  419. tmp = iIn;
  420. while ((ch = input[tmp++] | 0x20))
  421. {
  422. if ('0' <= ch <= '9')
  423. {
  424. colour = (colour << 4) | (ch - '0');
  425. }
  426. else if ('a' <= ch <= 'f')
  427. {
  428. colour = (colour << 4) | (ch - 'a' + 10);
  429. }
  430. else
  431. {
  432. if (tmp - iIn == 6)
  433. {
  434. iIn += 6;
  435. }
  436. else if (tmp - iIn > 3)
  437. {
  438. // Convert to 3 digit hex.
  439. // First strip off excess.
  440. colour >>>= 4 * (tmp - iIn - 4);
  441. iIn += 3;
  442. // Then dupilcate each value.
  443. colour = ((colour & 0x0F00) * 0x1100) | ((colour & 0x00F0) * 0x0110) | ((colour & 0x000F) * 0x0011);
  444. tmp = iIn;
  445. }
  446. else
  447. {
  448. // Invalid colour.
  449. iIn = tmp;
  450. colour = -1;
  451. }
  452. break;
  453. }
  454. if (tmp - iIn == 6)
  455. {
  456. iIn += 6;
  457. break;
  458. }
  459. }
  460. // Should never be reached. Is called if the string isn't long
  461. // enough to even contain a full colour identifier.
  462. //continue;
  463. if (tmp - iIn)
  464. {
  465. iIn = tmp - 1;
  466. continue;
  467. }
  468. goto Format_Standardise_no_switch;
  469. }
  470. case '~': // Game Text style information
  471. {
  472. /*if (fade)
  473. {
  474. // These never start and always close fades.
  475. fade = false;
  476. }*/
  477. colour = Format_GTToSAMP(input, iIn);
  478. goto Format_Standardise_no_switch;
  479. }
  480. case '(': // Bracket
  481. {
  482. //if (pt)
  483. //{
  484. // //if (iOut + 1 < len)
  485. // //{
  486. // /*if (fade)
  487. // {
  488. // fade = false;
  489. // }*/
  490. // input[iOut++] = '(';
  491. // //}
  492. // // Need more code here to handle players typing in colours,
  493. // // when they may just be putting in something in brackets -
  494. // // need to test if it matches a colour (or just use the "#"
  495. // // style (could make this user specified).
  496. //}
  497. //else
  498. //{
  499. if (iOut + 1 < len)
  500. {
  501. output[iOut++] = ch;
  502. }
  503. ++iIn;
  504. continue;
  505. //}
  506. }
  507. case '{': // Brace
  508. {
  509. /*if (fade)
  510. {
  511. fade = false;
  512. }*/
  513. colour = -3;
  514. }
  515. case '%':
  516. {
  517. ++iIn;
  518. if (pt)
  519. {
  520. // Don't allow players to type "%d", just output it as is.
  521. if (iOut + 1 < len)
  522. {
  523. output[iOut++] = ch;
  524. }
  525. }
  526. else
  527. {
  528. switch ((ch = input[iIn]))
  529. {
  530. case '%', '#', '{', '(', '~':
  531. {
  532. if (iOut + 1 < len)
  533. {
  534. output[iOut++] = ch;
  535. }
  536. ++iIn;
  537. }
  538. case '\0':
  539. {
  540. if (iOut + 1 < len)
  541. {
  542. output[iOut++] = '%';
  543. }
  544. }
  545. default:
  546. {
  547. ch = Format_GetSpecifier(input, iIn);
  548. if (ch)
  549. {
  550. if (e_COMPRESS_FORMAT_DATA:ch & e_COMPRESS_FORMAT_DATA_TYPE == e_COMPRESS_FORMAT_DATA_CUSTOM)
  551. {
  552. // If the return is
  553. // "e_COMPRESS_FORMAT_DATA_CUSTOM", then
  554. // "Format_GetSpecifier" doesn't increment
  555. // "iIn" enough so that we can read it here.
  556. if (input[iIn] == 'k')
  557. {
  558. P:7("Format_Standardise: \"k\" specifier %d, %d, %d", ch, iOut, len);
  559. // Slightly modified "my" style custom
  560. // specifier.
  561. //++iIn;
  562. if (input[iIn + 1] == '<' && (tmp = strfind(input, ">", false, iIn)) != -1)
  563. {
  564. // Compress the name and length.
  565. input[iIn] = tmp - iIn;
  566. input[iIn + 1] = 'k';
  567. input[tmp] = '\0';
  568. if (iOut + 2 + ceildiv(tmp - iIn, 4) <= len)
  569. {
  570. output[iOut++] = Y_FORMAT_IS_INSERT;
  571. output[iOut++] = ch;
  572. strpack(output[iOut], input[iIn], len);
  573. iOut += ceildiv(tmp - iIn, 4);
  574. }
  575. iIn = tmp + 1;
  576. }
  577. else
  578. {
  579. ++iIn;
  580. }
  581. }
  582. else
  583. {
  584. // "Slice" style custom specifier.
  585. P:7("Format_Standardise: Slice specifier %d, %d, %d", ch, iOut, len);
  586. if (iOut + 3 <= len)
  587. {
  588. output[iOut++] = Y_FORMAT_IS_INSERT;
  589. output[iOut++] = ch;
  590. static
  591. sFullName[4 char] = !"F@_";
  592. sFullName{2} = input[iIn];
  593. output[iOut++] = sFullName[0];
  594. }
  595. ++iIn;
  596. }
  597. }
  598. else
  599. {
  600. P:7("Format_Standardise: specifier %d, %d, %d", ch, iOut, len);
  601. if (iOut + 2 <= len)
  602. {
  603. output[iOut++] = Y_FORMAT_IS_INSERT;
  604. output[iOut++] = ch;
  605. }
  606. }
  607. }
  608. }
  609. }
  610. }
  611. Y_FORMAT_STRING_SKIP();
  612. continue;
  613. }
  614. case '\\':
  615. {
  616. ++iIn;
  617. if (pt)
  618. {
  619. // Don't allow players to type "\n", just output it as is.
  620. if (iOut + 1 < len)
  621. {
  622. output[iOut++] = ch;
  623. }
  624. }
  625. else
  626. {
  627. switch ((ch = input[iIn]))
  628. {
  629. Y_ESCAPES_CASE(r:\r);
  630. Y_ESCAPES_CASE(n:\n);
  631. Y_ESCAPES_CASE(a:\a);
  632. Y_ESCAPES_CASE(b:\b);
  633. Y_ESCAPES_CASE(v:\v);
  634. Y_ESCAPES_CASE(t:\t);
  635. Y_ESCAPES_CASE(e:\e);
  636. Y_ESCAPES_CASE(f:\f);
  637. Y_ESCAPES_CASE(s: );
  638. Y_ESCAPES_CASE(%:%);
  639. // These two with quotes can't be macros.
  640. case '\'': (iOut + 1 < len) && (output[iOut++] = '\''), ++iIn;
  641. case '"' : (iOut + 1 < len) && (output[iOut++] = '"' ), ++iIn;
  642. case 'x':
  643. {
  644. new
  645. num = 0;
  646. for ( ; ; )
  647. {
  648. // I don't know what the length restrictions on this
  649. // are - pawn-lang.pdf isn't clear.
  650. ch = input[++iIn];
  651. if ('0' <= ch <= '9')
  652. {
  653. num = (num * 16) + (ch - '0');
  654. }
  655. else if ('a' <= ch <= 'z')
  656. {
  657. num = (num * 16) + (ch - 'a' + 10);
  658. }
  659. else if ('A' <= ch <= 'Z')
  660. {
  661. num = (num * 16) + (ch - 'A' + 10);
  662. }
  663. else
  664. {
  665. break;
  666. }
  667. }
  668. if (ch == ';')
  669. {
  670. ++iIn;
  671. }
  672. if (iOut + 1 < len)
  673. {
  674. output[iOut++] = num;
  675. }
  676. }
  677. case '0' .. '9':
  678. {
  679. new
  680. num = ch - '0';
  681. ++iIn;
  682. // This can only be three characters.
  683. if ('0' <= (ch = input[iIn]) <= '9')
  684. {
  685. num = (num * 10) + (ch - '0');
  686. ++iIn;
  687. if ('0' <= (ch = input[iIn]) <= '9')
  688. {
  689. num = (num * 10) + (ch - '0');
  690. ch = input[++iIn];
  691. }
  692. }
  693. // To put a semi-colon straight after a number code, use
  694. // \; (I never knew what the point of that was before -
  695. // it's just a separator really here).
  696. if (ch == ';')
  697. {
  698. ++iIn;
  699. }
  700. if (iOut + 1 < len)
  701. {
  702. output[iOut++] = num;
  703. }
  704. }
  705. }
  706. }
  707. // Unrecognised symbols are ignored (or the slash is anyway).
  708. continue;
  709. }
  710. case '\01' .. '\04':
  711. {
  712. // Ignore these characters.
  713. ++iIn;
  714. continue;
  715. }
  716. case '\05' .. '\08', '\11', '\12', '\14' .. '\31':
  717. {
  718. // Excludes tabs and newlines.
  719. ++iIn;
  720. if (pt)
  721. {
  722. // Don't allow players to type "\05", just output it as is.
  723. // They can't actually type this, but just in case!
  724. if (iOut + 1 < len)
  725. {
  726. // Make all these things spaces.
  727. output[iOut++] = ' ';
  728. }
  729. }
  730. else
  731. {
  732. // Don't allow players to type "\05", just output it as is.
  733. // They can't actually type this, but just in case!
  734. if (iOut + 1 < len)
  735. {
  736. // Make all these things spaces.
  737. output[iOut++] = ch;
  738. }
  739. }
  740. continue;
  741. }
  742. default:
  743. {
  744. // Just add the character.
  745. if (iOut + 1 < len)
  746. {
  747. output[iOut++] = ch;
  748. }
  749. ++iIn;
  750. continue;
  751. }
  752. }
  753. P:7("Format_Standardise: loop pt 2");
  754. switch ((ch = input[++iIn]))
  755. {
  756. case '>':
  757. {
  758. // Start of a fade.
  759. //if (!fade)
  760. //{
  761. fade = true;
  762. //}
  763. ch = input[++iIn];
  764. if (ch == '[')
  765. {
  766. steps = 0;
  767. while ((ch = input[++iIn]))
  768. {
  769. // Parse the number of steps to use.
  770. if (ch == ']')
  771. {
  772. ch = input[++iIn];
  773. break;
  774. }
  775. else if ('0' <= ch <= '9')
  776. {
  777. steps = (steps * 10) + (ch - '0');
  778. }
  779. else
  780. {
  781. // INNER LOOP, NOT THE MAIN LOOP.
  782. continue;
  783. }
  784. }
  785. }
  786. }
  787. case '<':
  788. {
  789. // End of a fade.
  790. /*if (fade)
  791. {
  792. fade = false;
  793. }*/
  794. ch = input[++iIn];
  795. }
  796. }
  797. P:7("Format_Standardise: loop pt 3");
  798. // Close colours introduced by [FeK]DraKiNs.
  799. if (colour == -2)
  800. {
  801. colour = ')';
  802. }
  803. else
  804. {
  805. colour = '}';
  806. }
  807. if (ch == '/')
  808. {
  809. // Close colour.
  810. while ((ch = input[++iIn]))
  811. {
  812. if (ch == colour)
  813. {
  814. ++iIn;
  815. break;
  816. }
  817. }
  818. // Ignore everything else, skip to the after bit.
  819. colour = -2;
  820. goto Format_Standardise_no_switch;
  821. }
  822. // Finally we can get the real colour.
  823. new
  824. tot = 0,
  825. bool:num = true,
  826. cur = iIn;
  827. //idx = iIn;
  828. P:7("Format_Standardise: loop pt 4");
  829. while (ch)
  830. {
  831. if (ch == colour)
  832. {
  833. break;
  834. }
  835. new
  836. ch2 = ch | 0x20;
  837. if (num)
  838. {
  839. // Check if it's still a valid HEX digit and increment.
  840. if ('0' <= ch <= '9')
  841. {
  842. tot = (tot << 4) | (ch - '0');
  843. }
  844. else if ('a' <= ch2 <= 'f')
  845. {
  846. tot = (tot << 4) | (ch2 - 'a' + 10);
  847. }
  848. else if (('g' <= ch2 <= 'z') || ch == '_' || ch == ' ')
  849. {
  850. // No, but still a valid identifier.
  851. num = false;
  852. }
  853. else
  854. {
  855. colour = -1;
  856. goto Format_Standardise_no_switch;
  857. }
  858. }
  859. else if (!(('0' <= ch <= '9') || ('a' <= ch2 <= 'z') || ch == '_' || ch == ' '))
  860. {
  861. // Not a valid identifier character.
  862. colour = -1;
  863. // Can't use "continue" here as we're in an inner loop.
  864. goto Format_Standardise_no_switch;
  865. }
  866. ch = input[++cur];
  867. }
  868. P:7("Format_Standardise: loop pt 5 %c %d %d %d %s", ch, iIn, cur, num, input[iIn]);
  869. //while ((ch = input[++idx]));
  870. if (ch == '\0')
  871. {
  872. // Not a valid end.
  873. //iIn = cur;
  874. continue;
  875. }
  876. ++cur;
  877. if (cur == iIn + 1)
  878. {
  879. ++iIn;
  880. continue;
  881. }
  882. if (num)
  883. {
  884. // The input was a number.
  885. colour = tot & 0x00FFFFFF;
  886. }
  887. else
  888. {
  889. // The input was a string.
  890. //if (input[iIn] | 0x20 == 'x' && input[iIn + 1] == '1' && input[iIn + 2] == '1')
  891. #if _YSI_USE_X11
  892. if (!strcmp(input[iIn], "X11", true, 3))
  893. {
  894. if (input[iIn + 3] == ' ' || input[iIn + 3] == '_')
  895. {
  896. colour = GetColourHash(YHash(input[iIn + 4], false, hash_bernstein, cur - iIn - 5), 1);
  897. }
  898. else
  899. {
  900. colour = GetColourHash(YHash(input[iIn + 3], false, hash_bernstein, cur - iIn - 4), 1);
  901. }
  902. }
  903. else
  904. #endif
  905. {
  906. colour = GetColourHash(YHash(input[iIn], false, hash_bernstein, cur - iIn - 1), 1);
  907. }
  908. #pragma tabsize 4
  909. if (!colour)
  910. {
  911. continue;
  912. }
  913. colour >>>= 8;
  914. }
  915. P:7("Format_Standardise: loop pt 6");
  916. iIn = cur;
  917. // One of the FEW labels in my code, because in here "break" ends the
  918. // loop enclosing the switch statement, instead of ending the current
  919. // case from the switch statement as in C.
  920. Format_Standardise_no_switch:
  921. if (colour == -1)
  922. {
  923. continue;
  924. }
  925. else if (colour == -2)
  926. {
  927. if (iOut + 2 < len)
  928. {
  929. // Save the close.
  930. colour = Y_FORMAT_CLOSE_CURR;
  931. if (fade)
  932. {
  933. colour |= Y_FORMAT_START_FADE;
  934. }
  935. output[iOut++] = Y_FORMAT_IS_COLOUR;
  936. output[iOut++] = colour | Y_FORMAT_ALWAYS_SET;
  937. }
  938. }
  939. else if (colour & 0x0F000000)
  940. {
  941. // Players can't type these special things.
  942. if (!pt && iOut + 2 < len)
  943. {
  944. // Save the custom key.
  945. output[iOut++] = Y_FORMAT_IS_KEY;
  946. if (colour & 0xFF == 'k')
  947. {
  948. // Add the whole next key definition.
  949. ch = _:Format_GetKeys(input, iIn);
  950. if (ch != _:e_NO_KEY_SELECTED)
  951. {
  952. output[iOut++] = 'k' | (ch << 8);
  953. }
  954. }
  955. else
  956. {
  957. switch (colour & 0xFF)
  958. {
  959. case 'n':
  960. {
  961. output[iOut++] = '\n';
  962. }
  963. case ']':
  964. {
  965. output[iOut++] = '*';
  966. }
  967. default:
  968. {
  969. output[iOut++] = (colour & 0xFF) | Y_FORMAT_ALWAYS_SET;
  970. }
  971. }
  972. colour = colour >> 8 & 0xFF;
  973. if (iOut + 2 < len && colour)
  974. {
  975. // Save the special GameText "lighter" colour.
  976. output[iOut++] = Y_FORMAT_IS_COLOUR;
  977. output[iOut++] = colour | Y_FORMAT_GT_LIGHTER | Y_FORMAT_ALWAYS_SET;
  978. }
  979. }
  980. }
  981. }
  982. else
  983. {
  984. if (iOut + 2 < len)
  985. {
  986. // Save the normal colour.
  987. if (fade)
  988. {
  989. colour |= Y_FORMAT_START_FADE;
  990. }
  991. output[iOut++] = Y_FORMAT_IS_COLOUR;
  992. output[iOut++] = colour | Y_FORMAT_ALWAYS_SET;
  993. }
  994. }
  995. Y_FORMAT_STRING_SKIP();
  996. P:7("Format_Standardise: loop pt 7");
  997. }
  998. output[iOut] = '\0';
  999. /*if (lastChar == iOut + 1)
  1000. {
  1001. output[lastChar] = 0;
  1002. }
  1003. else
  1004. {
  1005. output[lastChar] = iOut;
  1006. }*/
  1007. P:5("Format_Standardise: end: %d %d,%d,%d,%d,%d", iOut, output[0], output[1], output[2], output[3], output[4]);
  1008. /*else
  1009. {
  1010. return GetColourHash(YHash(input[start], false, hash_bernstein, cur - start - 1), 0) >>> 8;
  1011. }*/
  1012. return iOut;
  1013. }
  1014. /**--------------------------------------------------------------------------**\
  1015. <summary>Format_GetSpecifier</summary>
  1016. <param name="input[]">String to read from.</param>
  1017. <param name="&iIn">Index to read from.</param>
  1018. <returns>
  1019. Single cell representation of the current specifier.
  1020. </returns>
  1021. <remarks>
  1022. Reads a series of characters from the input string and interprets them as a
  1023. format specifier (e.g. "%d"). Also returns the new current string index.
  1024. </remarks>
  1025. \**--------------------------------------------------------------------------**/
  1026. static stock Format_GetSpecifier(input[], &iIn)
  1027. {
  1028. P:4("Format_GetSpecifier called: \"%s\", %i", input, iIn);
  1029. new
  1030. ch = input[iIn],
  1031. e_COMPRESS_FORMAT_DATA:ret = e_COMPRESS_FORMAT_DATA:0,
  1032. width,
  1033. prec = -1;
  1034. for ( ; ; )
  1035. {
  1036. switch (ch)
  1037. {
  1038. case '\0':
  1039. {
  1040. break;
  1041. }
  1042. case '!':
  1043. {
  1044. ret = (ret & ~e_COMPRESS_FORMAT_DATA_FUNC) | e_COMPRESS_FORMAT_DATA_LIST;
  1045. }
  1046. case '?':
  1047. {
  1048. ret = (ret & ~e_COMPRESS_FORMAT_DATA_LIST) | e_COMPRESS_FORMAT_DATA_FUNC;
  1049. }
  1050. case '-':
  1051. {
  1052. ret |= e_COMPRESS_FORMAT_DATA_LEFT;
  1053. }
  1054. case '.':
  1055. {
  1056. if ((ch = input[++iIn]) == '*')
  1057. {
  1058. prec = 0x800;
  1059. }
  1060. else
  1061. {
  1062. prec = 0;
  1063. while ('0' <= ch <= '9')
  1064. {
  1065. prec = 10 * prec + (ch - '0');
  1066. ch = input[++iIn];
  1067. }
  1068. }
  1069. continue;
  1070. }
  1071. case '0':
  1072. {
  1073. ret |= e_COMPRESS_FORMAT_DATA_ZERO;
  1074. }
  1075. case '1' .. '9':
  1076. {
  1077. width = 0;
  1078. do
  1079. {
  1080. width = 10 * width + (ch - '0');
  1081. ch = input[++iIn];
  1082. }
  1083. while ('0' <= ch <= '9');
  1084. continue;
  1085. }
  1086. case '*':
  1087. {
  1088. width = 0x800;
  1089. }
  1090. case 's':
  1091. {
  1092. ++iIn;
  1093. if (ret & e_COMPRESS_FORMAT_DATA_LIST)
  1094. {
  1095. printf("*** Internal Warning: Ignoring string list format specifier.");
  1096. ret &= e_COMPRESS_FORMAT_DATA_LIST;
  1097. }
  1098. return ret | e_COMPRESS_FORMAT_DATA_STRING | (e_COMPRESS_FORMAT_DATA:((width & 0xFFF) | ((prec & 0xFFF) << 12)));
  1099. }
  1100. Y_COLOURS_CASE(b:BIN);
  1101. Y_COLOURS_CASE(d','i:DEC);
  1102. Y_COLOURS_CASE(h','x:HEX);
  1103. Y_COLOURS_CASE(f:FLOAT);
  1104. Y_COLOURS_CASE(g:IEEE);
  1105. Y_COLOURS_CASE(o:OCT);
  1106. // I *might* half-decouple "%n" so that this doesn't directly rely
  1107. // on y_commands being included first. Or I could do what y_classes
  1108. // does to use y_groups without including it directly.
  1109. Y_COLOURS_CASE(n:COMM);
  1110. Y_COLOURS_CASE(p:SUFFIX);
  1111. Y_COLOURS_CASE(u:UNSIGNED);
  1112. Y_COLOURS_CASE(t:SIGNED);
  1113. Y_COLOURS_CASE(q:PLAYER);
  1114. Y_COLOURS_CASE(l:LOGICAL);
  1115. default:
  1116. {
  1117. // I have removed the "%DATE% sequence and replaced it with the
  1118. // custom system from Slice. Ideally I'd like to support both
  1119. // somehow, like make the "%XYZ%" format an option AND the "%q"
  1120. // format an option - maybe default to mine and fall back on the
  1121. // short version if a function isn't found.
  1122. /*if (!strcmp(input, !"DATE%", true, 5))
  1123. {
  1124. iIn += 5;
  1125. return ret | e_COMPRESS_FORMAT_DATA_DATE | (e_COMPRESS_FORMAT_DATA:((width & 0xFFF) | ((prec & 0xFFF) << 12)));
  1126. }*/
  1127. // Shut up the compiler.
  1128. //break;
  1129. return ret | e_COMPRESS_FORMAT_DATA_CUSTOM | (e_COMPRESS_FORMAT_DATA:((width & 0xFFF) | ((prec & 0xFFF) << 12)));
  1130. }
  1131. }
  1132. ch = input[++iIn];
  1133. }
  1134. return 0;
  1135. }
  1136. /**--------------------------------------------------------------------------**\
  1137. <summary>Format_GTToSAMP</summary>
  1138. <param name="const str[]">Input.</param>
  1139. <param name="&idx">Read index.</param>
  1140. <returns>
  1141. Colour.
  1142. </returns>
  1143. <remarks>
  1144. Reads a GameText colour format and converts it to single-cell RGB.
  1145. </remarks>
  1146. \**--------------------------------------------------------------------------**/
  1147. static stock Format_GTToSAMP(const str[], &idx)
  1148. {
  1149. P:4("Format_GTToSAMP called: \"%s\", %i", str, idx);
  1150. new
  1151. cur = idx;
  1152. if (str[cur] == '~')
  1153. {
  1154. // Check the colour is correctly ended.
  1155. new
  1156. t = str[++cur];
  1157. if (!t)
  1158. {
  1159. ++idx;
  1160. return -1;
  1161. }
  1162. if (str[++cur] != '~')
  1163. {
  1164. ++idx;
  1165. return -1;
  1166. }
  1167. ++cur;
  1168. // Get the number of ~h~s after the colour.
  1169. new
  1170. c = 0;
  1171. while (str[cur] == '~')
  1172. {
  1173. if (str[cur + 1] | 0x20 == 'h' && str[cur + 2] == '~')
  1174. {
  1175. ++c;
  1176. cur += 3;
  1177. }
  1178. else
  1179. {
  1180. break;
  1181. }
  1182. }
  1183. idx = cur;
  1184. // Return the correct colour for the given string.
  1185. switch (t)
  1186. {
  1187. case 'b':
  1188. {
  1189. switch (c)
  1190. {
  1191. case 0:
  1192. return SAMP_GAME_TEXT_B >>> 8;
  1193. case 1:
  1194. return SAMP_GAME_TEXT_BH >>> 8;
  1195. case 2:
  1196. return SAMP_GAME_TEXT_BHH >>> 8;
  1197. case 3:
  1198. return SAMP_GAME_TEXT_BHHH >>> 8;
  1199. default:
  1200. return SAMP_GAME_TEXT_W >>> 8;
  1201. }
  1202. }
  1203. case 'g':
  1204. {
  1205. switch (c)
  1206. {
  1207. case 0:
  1208. return SAMP_GAME_TEXT_G >>> 8;
  1209. case 1:
  1210. return SAMP_GAME_TEXT_GH >>> 8;
  1211. case 2:
  1212. return SAMP_GAME_TEXT_GHH >>> 8;
  1213. case 3:
  1214. return SAMP_GAME_TEXT_GHHH >>> 8;
  1215. case 4:
  1216. return SAMP_GAME_TEXT_GHHHH >>> 8;
  1217. default:
  1218. return SAMP_GAME_TEXT_W >>> 8;
  1219. }
  1220. }
  1221. case 'h':
  1222. {
  1223. switch (c)
  1224. {
  1225. case 0:
  1226. return SAMP_GAME_TEXT_H >>> 8;
  1227. case 1:
  1228. return SAMP_GAME_TEXT_HH >>> 8;
  1229. default:
  1230. return SAMP_GAME_TEXT_W >>> 8;
  1231. }
  1232. }
  1233. case 'l':
  1234. {
  1235. return SAMP_GAME_TEXT_L >>> 8;
  1236. }
  1237. case 'p':
  1238. {
  1239. switch (c)
  1240. {
  1241. case 0:
  1242. return SAMP_GAME_TEXT_P >>> 8;
  1243. case 1:
  1244. return SAMP_GAME_TEXT_PH >>> 8;
  1245. case 2:
  1246. return SAMP_GAME_TEXT_PHH >>> 8;
  1247. default:
  1248. return SAMP_GAME_TEXT_W >>> 8;
  1249. }
  1250. }
  1251. case 'r':
  1252. {
  1253. switch (c)
  1254. {
  1255. case 0:
  1256. return SAMP_GAME_TEXT_R >>> 8;
  1257. case 1:
  1258. return SAMP_GAME_TEXT_RH >>> 8;
  1259. case 2:
  1260. return SAMP_GAME_TEXT_RHH >>> 8;
  1261. case 3:
  1262. return SAMP_GAME_TEXT_RHHH >>> 8;
  1263. case 4:
  1264. return SAMP_GAME_TEXT_RHHHH >>> 8;
  1265. case 5:
  1266. return SAMP_GAME_TEXT_RHHHHH >>> 8;
  1267. default:
  1268. return SAMP_GAME_TEXT_W >>> 8;
  1269. }
  1270. }
  1271. case 'w':
  1272. {
  1273. return SAMP_GAME_TEXT_W >>> 8;
  1274. }
  1275. case 'y':
  1276. {
  1277. switch (c)
  1278. {
  1279. case 0:
  1280. return SAMP_GAME_TEXT_Y >>> 8;
  1281. case 1:
  1282. return SAMP_GAME_TEXT_YH >>> 8;
  1283. case 2:
  1284. return SAMP_GAME_TEXT_YHH >>> 8;
  1285. default:
  1286. return SAMP_GAME_TEXT_W >>> 8;
  1287. }
  1288. }
  1289. default:
  1290. {
  1291. // Return the fact there is a different GT sequence but keep a
  1292. // record of the number of hs which came after it to avoid
  1293. // excess processing.
  1294. //idx -= (c + 1) * 3;
  1295. return 0x0F000000 | t | (c << 8);
  1296. }
  1297. }
  1298. }
  1299. return -1;
  1300. }