AXV09

Formatex - by Slice

Dec 22nd, 2012
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.18 KB | None | 0 0
  1. #if defined FORMAT_EXTRA_TAGS
  2. #define FORMAT_TAGS _, PlayerText3D, Text, Text3D, Menu, DB, DBResult, File, Float, FORMAT_EXTRA_TAGS
  3. #else
  4. #define FORMAT_TAGS _, PlayerText3D, Text, Text3D, Menu, DB, DBResult, File, Float
  5. #endif
  6.  
  7. #if !defined FORMAT_BUFFER_SIZE
  8. #define FORMAT_BUFFER_SIZE 2048
  9. #endif
  10.  
  11. #if !defined FORMAT_PRINT_BUFFER_SIZE
  12. #define FORMAT_PRINT_BUFFER_SIZE 512
  13. #endif
  14.  
  15. #if !defined FORMAT_CUSTOM_SPEC_BUFFER_SIZE
  16. #define FORMAT_CUSTOM_SPEC_BUFFER_SIZE 512
  17. #endif
  18.  
  19. #if !defined FORMAT_REPLACE_NATIVES
  20. #define FORMAT_REPLACE_NATIVES true
  21. #endif
  22.  
  23. #define formatSpecifier<'%1'>(%2[%3],%4) FMAT@1:F@%1(%2[FORMAT_CUSTOM_SPEC_BUFFER_SIZE],FMAT@2:___unused,%4)
  24. #define FMAT@2:___unused,%1[ %1[
  25. #define FMAT@1:%1(%2) forward %1(%2); public %1(%2)
  26.  
  27. static stock
  28. gs_CustomFormatFunctions[127] = {-1, ...},
  29. bool:gs_bIsInitialized = false
  30. ;
  31.  
  32. forward __fmt_funcinc();
  33. public __fmt_funcinc() {
  34.  
  35. new szOutput[1];
  36. format(szOutput, 0, "");
  37. }
  38.  
  39. static stock InitializeFormatSpecifiers() {
  40.  
  41. new szFunctionName[4 char] = !"F@_",
  42. iIndex,
  43. iFunctionAddress
  44. ;
  45.  
  46. gs_bIsInitialized = true;
  47.  
  48. for (new c = '@'; c <= 'z'; c++) {
  49. // Skip the chars that can't be used in function names
  50. if (c == 'Z' + 1)
  51. c = '_';
  52. else if (c == '_' + 1)
  53. c = 'a';
  54.  
  55. szFunctionName{2} = c;
  56.  
  57. // Get the function's address if it exists
  58. if (-1 != (iIndex = funcidx(szFunctionName))) {
  59. #emit LCTRL 1
  60. #emit NEG
  61. #emit MOVE.alt
  62. #emit ADD.C 32
  63. #emit STOR.S.pri iFunctionAddress
  64. #emit LREF.S.pri iFunctionAddress
  65. #emit ADD
  66. #emit LOAD.S.alt iIndex
  67. #emit SHL.C.alt 3
  68. #emit ADD
  69. #emit STOR.S.pri iFunctionAddress
  70. #emit LREF.S.pri iFunctionAddress
  71. #emit STOR.S.pri iFunctionAddress
  72.  
  73. gs_CustomFormatFunctions[c] = iFunctionAddress;
  74. }
  75. }
  76. }
  77.  
  78. formatex(szOutput[], iLength = sizeof(szOutput), const szFormatString[], {FORMAT_TAGS}:...) {
  79.  
  80. static s_szBuffer[FORMAT_BUFFER_SIZE],
  81. bool:s_bIsInCustomSpecifier = false
  82. ;
  83.  
  84. if (s_bIsInCustomSpecifier) {
  85.  
  86. new iNumArgs,
  87. i
  88. ;
  89.  
  90. #emit LOAD.S.pri 8
  91. #emit STOR.S.pri iNumArgs
  92. #emit SHR.C.pri 2
  93. #emit STOR.S.pri i
  94.  
  95. while (--i >= 0) {
  96. #emit LOAD.S.pri i
  97. #emit SHL.C.pri 2
  98. #emit ADD.C 12
  99. #emit MOVE.alt
  100. #emit LCTRL 5
  101. #emit ADD
  102. #emit LOAD.I
  103. #emit PUSH.pri
  104. }
  105.  
  106. #emit LOAD.S.pri iNumArgs
  107. #emit PUSH.pri
  108. #emit MOVE.alt
  109. #emit SYSREQ.C format
  110. #emit CONST.pri 4
  111. #emit ADD
  112. #emit MOVE.alt
  113. #emit LCTRL 4
  114. #emit ADD
  115. #emit SCTRL 4
  116. } else {
  117.  
  118. new iPos = -1,
  119. iArg = 12 + (3 * 4),
  120. iArgCount,
  121. iAddress,
  122. iArgValue,
  123. aiArgs[128],
  124. i
  125. ;
  126.  
  127. if (!gs_bIsInitialized)
  128. InitializeFormatSpecifiers();
  129.  
  130. iLength = min(FORMAT_BUFFER_SIZE, iLength);
  131.  
  132. s_szBuffer[0] = 0;
  133.  
  134. strunpack(s_szBuffer, szFormatString);
  135.  
  136. while (-1 != (iPos = strfind(s_szBuffer, !"%", _, ++iPos))) {
  137. while (s_szBuffer[++iPos]) {
  138. // Look for custom formats
  139. if (1 <= s_szBuffer[iPos] < sizeof(gs_CustomFormatFunctions) && gs_CustomFormatFunctions[s_szBuffer[iPos]] != -1) {
  140. new
  141. iFunc = gs_CustomFormatFunctions[s_szBuffer[iPos]]
  142. ;
  143.  
  144. static
  145. s_szCustomFormatBuffer[FORMAT_CUSTOM_SPEC_BUFFER_SIZE]
  146. ;
  147.  
  148. strdel(s_szBuffer, iPos - 1, iPos + 1);
  149.  
  150. s_szCustomFormatBuffer[0] = 0;
  151.  
  152. #emit LCTRL 5
  153. #emit LOAD.S.alt iArg
  154. #emit ADD
  155. #emit LOAD.I
  156. #emit MOVE.alt
  157. #emit LOAD.I
  158. #emit PUSH.pri
  159. #emit PUSH.alt
  160.  
  161. iArg += 4;
  162.  
  163. s_bIsInCustomSpecifier = true;
  164.  
  165. #emit PUSH.C s_szCustomFormatBuffer
  166. #emit PUSH.C 12
  167. #emit LCTRL 6
  168. #emit ADD.C 28
  169. #emit PUSH.pri
  170. #emit LOAD.S.pri iFunc
  171. #emit SCTRL 6
  172.  
  173. s_bIsInCustomSpecifier = false;
  174.  
  175. strins(s_szBuffer, s_szCustomFormatBuffer, iPos - 1);
  176.  
  177. break;
  178. }
  179.  
  180. switch (s_szBuffer[iPos]) {
  181. // Handled by the original format function
  182. case '*', 'i', 'd', 'x', 'h', 'c', 's', 'f', 'b': {
  183. // Get the argument address and save it for later
  184. #emit LCTRL 5
  185. #emit LOAD.S.alt iArg
  186. #emit ADD
  187. #emit LOAD.I
  188. #emit STOR.S.pri iAddress
  189. #emit MOVE.pri
  190. #emit ADD.C 4
  191. #emit STOR.S.pri iArg
  192.  
  193. aiArgs[iArgCount++] = iAddress;
  194.  
  195. if (s_szBuffer[iPos] == '*')
  196. continue;
  197.  
  198. break;
  199. }
  200.  
  201. // Unsigned numbers
  202. case 'u': {
  203. new szBuffer[11];
  204.  
  205. #emit LCTRL 5
  206. #emit LOAD.S.alt iArg
  207. #emit ADD
  208. #emit LOAD.I
  209. #emit LOAD.I
  210. #emit STOR.S.pri iArgValue
  211. #emit MOVE.pri
  212. #emit ADD.C 4
  213. #emit STOR.S.pri iArg
  214.  
  215. strdel(s_szBuffer, iPos - 1, iPos + 1);
  216.  
  217. if (!iArgValue)
  218. strins(s_szBuffer, "0", iPos - 1);
  219. else {
  220. new
  221. j = sizeof(szBuffer) - 1
  222. ;
  223.  
  224. while (iArgValue) {
  225. // szBuffer[--i]
  226. #emit ADDR.alt szBuffer // alt = *szBuffer
  227. #emit LOAD.S.pri j // pri = i
  228. #emit DEC.pri // pri -= 1
  229. #emit STOR.S.pri j // i = pri
  230. #emit IDXADDR // pri = alt + i * 4
  231. #emit PUSH.pri // Store pri for later
  232.  
  233. // Now do an unsigned divide on uValue then use both the quotient and remainder!
  234. #emit LOAD.S.pri iArgValue // pri = uValue
  235. #emit CONST.alt 10
  236. #emit UDIV // pri = uValue / 10; alt = uValue % 10
  237. #emit STOR.S.pri iArgValue // uValue = pri
  238. #emit CONST.pri '0'
  239. #emit ADD // pri = '0' + (uValue % 10)
  240. #emit POP.alt // alt = szBuffer[i]
  241. #emit STOR.I // szBuffer[i] = pri
  242. }
  243.  
  244. strins(s_szBuffer, szBuffer[j], iPos - 1);
  245. }
  246. }
  247.  
  248. case '0' .. '9', ' ', '.': continue;
  249.  
  250. case '%': break;
  251.  
  252. default: break;
  253. }
  254. }
  255. }
  256.  
  257. i = iArgCount;
  258.  
  259. // Push the arguments we stored above
  260. while (--i >= 0) {
  261. #emit ADDR.alt aiArgs
  262. #emit LOAD.S.pri i
  263. #emit LIDX
  264. #emit PUSH.pri
  265. #emit STOR.S.pri iAddress
  266. }
  267.  
  268. // New format specifier
  269. #emit PUSH.C s_szBuffer
  270.  
  271. // Max length
  272. #emit PUSH.S iLength
  273.  
  274. // Output string
  275. #emit PUSH.S szOutput
  276.  
  277. // Argument count
  278. #emit LOAD.S.pri iArgCount
  279. #emit SHL.C.pri 2
  280. #emit ADD.C 12
  281. #emit PUSH.pri
  282.  
  283. // Save the argument count for later
  284. #emit MOVE.alt
  285.  
  286. // Call format (duh)
  287. #emit SYSREQ.C format
  288.  
  289. // Add 4 to the argument count
  290. #emit CONST.pri 4
  291. #emit ADD
  292. #emit MOVE.alt
  293.  
  294. // Remove <argument count> from the stack
  295. #emit LCTRL 4
  296. #emit ADD
  297. #emit SCTRL 4
  298. }
  299.  
  300. // Return in case anyone uses it
  301. return 1;
  302. }
  303.  
  304. va_formatex(output[], size = sizeof(output), const fmat[], va_:STATIC_ARGS) {
  305.  
  306. new num_args,
  307. arg_start,
  308. arg_end
  309. ;
  310.  
  311. // Get the pointer to the number of arguments to the last function.
  312. #emit LOAD.S.pri 0
  313. #emit ADD.C 8
  314. #emit MOVE.alt
  315. // Get the number of arguments.
  316. #emit LOAD.I
  317. #emit STOR.S.pri num_args
  318. // Get the variable arguments (end).
  319. #emit ADD
  320. #emit STOR.S.pri arg_end
  321. // Get the variable arguments (start).
  322. #emit LOAD.S.pri STATIC_ARGS
  323. #emit SMUL.C 4
  324. #emit ADD
  325. #emit STOR.S.pri arg_start
  326. // Using an assembly loop here screwed the code up as the labels added some
  327. // odd stack/frame manipulation code...
  328. while (arg_end != arg_start) {
  329. #emit MOVE.pri
  330. #emit LOAD.I
  331. #emit PUSH.pri
  332. #emit CONST.pri 4
  333. #emit SUB.alt
  334. #emit STOR.S.pri arg_end
  335. }
  336. // Push the additional parameters.
  337. #emit PUSH.S fmat
  338. #emit PUSH.S size
  339. #emit PUSH.S output
  340. // Push the argument count.
  341. #emit LOAD.S.pri num_args
  342. #emit ADD.C 12
  343. #emit LOAD.S.alt STATIC_ARGS
  344. #emit XCHG
  345. #emit SMUL.C 4
  346. #emit SUB.alt
  347. #emit PUSH.pri
  348. #emit MOVE.alt
  349. // Push the return address.
  350. #emit LCTRL 6
  351. #emit ADD.C 28
  352. #emit PUSH.pri
  353. // Call formatex
  354. #emit CONST.pri formatex
  355. #emit SCTRL 6
  356. }
  357.  
  358. stock printfex(const szFormatString[], {FORMAT_TAGS}:...) {
  359.  
  360. const iBufferSize = FORMAT_PRINT_BUFFER_SIZE;
  361.  
  362. static s_szBuffer[FORMAT_PRINT_BUFFER_SIZE];
  363.  
  364. new iNumArgs = numargs(),
  365. i = iNumArgs - 1
  366. ;
  367.  
  368. while (--i >= 0) {
  369. #emit LOAD.S.pri i
  370. #emit SHL.C.pri 2
  371. #emit ADD.C 16
  372. #emit MOVE.alt
  373. #emit LCTRL 5
  374. #emit ADD
  375. #emit LOAD.I
  376. #emit PUSH.pri
  377. }
  378.  
  379. #emit PUSH.S szFormatString
  380. #emit PUSH.C iBufferSize
  381. #emit PUSH.C s_szBuffer
  382. #emit LOAD.S.pri iNumArgs
  383. #emit SHL.C.pri 2
  384. #emit ADD.C 8
  385. #emit PUSH.pri
  386. #emit LCTRL 6
  387. #emit ADD.C 28
  388. #emit PUSH.pri
  389. #emit CONST.pri formatex
  390. #emit SCTRL 6
  391.  
  392. print(s_szBuffer);
  393. }
  394.  
  395. // ---------------------------------------
  396. // Specifiers
  397. // ---------------------------------------
  398.  
  399. // Inline color
  400. formatSpecifier<'C'>(output[], color) {
  401.  
  402. format(output, sizeof(output), "{%06x}", color >>> 8);
  403. }
  404.  
  405. // Player name
  406. formatSpecifier<'p'>(output[], playerid) {
  407.  
  408. if (0 <= playerid < GetMaxPlayers() && IsPlayerConnected(playerid))
  409. GetPlayerName(playerid, output, sizeof(output));
  410. else
  411. strcat(output, "<UNKNOWN>");
  412. }
  413.  
  414. // Player name and color
  415. formatSpecifier<'P'>(output[], playerid) {
  416.  
  417. if (0 <= playerid < GetMaxPlayers() && IsPlayerConnected(playerid)) {
  418. format(output, sizeof(output), "{%06x}", GetPlayerColor(playerid) >>> 8);
  419.  
  420. GetPlayerName(playerid, output[8], sizeof(output) - 8);
  421. } else
  422. strcat(output, "{FFFFFF}<UNKNOWN>");
  423. }
  424.  
  425. // Weapon name
  426. formatSpecifier<'W'>(output[], weapon) {
  427.  
  428. static const
  429. s_WeaponNames[][] = {
  430. {!"Fists" }, {!"Knuckles" }, {!"Golfclub" }, // 0, 1, 2
  431. {!"Nightstick" }, {!"Knife" }, {!"Bat" }, // 3, 4, 5
  432. {!"Shovel" }, {!"Pool Cue" }, {!"Katana" }, // 6, 7, 8
  433. {!"Chainsaw" }, {!"Dildo" }, {!"Vibrator" }, // 9, 10, 11
  434. {!"Vibrator" }, {!"Vibrator" }, {!"Flowers" }, // 12, 13, 14
  435. {!"Cane" }, {!"Grenade" }, {!"Teargas" }, // 15, 16, 17
  436. {!"Molotov" }, {!"" }, {!"" }, // 18, ,
  437. {!"" }, {!"9mm" }, {!"Silenced Pistol"}, // , 22, 23
  438. {!"Deagle" }, {!"Shotgun" }, {!"Sawnoffs" }, // 24, 25, 26
  439. {!"Combat Shotgun" }, {!"Mac-10" }, {!"MP5" }, // 27, 28, 29
  440. {!"AK-47" }, {!"M4" }, {!"Tec-9" }, // 30, 31, 32
  441. {!"Cuntgun" }, {!"Sniper" }, {!"Rocketlauncher" }, // 33, 34, 35
  442. {!"Heatseeking RPG"}, {!"Flamethrower"}, {!"Minigun" }, // 36, 37, 38
  443. {!"Satchel" }, {!"Detonator" }, {!"Spraycan" }, // 39, 40, 41
  444. {!"Extinguisher" }, {!"Camera" }, {!"Nightvision" }, // 42, 43, 44
  445. {!"Infrared" }, {!"Parachute" }, {!"Fake Pistol" }, // 45, 46, 47
  446. {!"" }, {!"Vehicle" }, {!"Helikill" }, // , 49, 50
  447. {!"Explosion" }, {!"" }, {!"Drown" }, // 51, , 53
  448. {!"Collision" }, {!"Splat" }, {!"Unknown" } // 54, 55, 56
  449. }
  450. ;
  451.  
  452. if (0 <= weapon < sizeof(s_WeaponNames))
  453. strcat(output, s_WeaponNames[weapon]);
  454. else
  455. strcat(output, "Unknown");
  456. }
  457.  
  458. // Weapon name, lower-case singular (for sentences)
  459. formatSpecifier<'w'>(output[], weapon) {
  460. static const
  461. s_WeaponNamesLowercaseSingular[][] = {
  462. {!"fists" }, {!"knuckles" }, {!"a golfclub" }, // 0, 1, 2
  463. {!"a nightstick" }, {!"a knife" }, {!"a bat" }, // 3, 4, 5
  464. {!"a shovel" }, {!"a pool cue" }, {!"a katana" }, // 6, 7, 8
  465. {!"a chainsaw" }, {!"a dildo" }, {!"a vibrator" }, // 9, 10, 11
  466. {!"a vibrator" }, {!"a vibrator" }, {!"flowers" }, // 12, 13, 14
  467. {!"a cane" }, {!"a grenade" }, {!"teargas" }, // 15, 16, 17
  468. {!"a molotov" }, {!"" }, {!"" }, // 18, ,
  469. {!"" }, {!"a 9mm" }, {!"a silenced pistol"}, // , 22, 23
  470. {!"a deagle" }, {!"a shotgun" }, {!"sawnoffs" }, // 24, 25, 26
  471. {!"a combat shotgun" }, {!"a mac-10" }, {!"an mp5" }, // 27, 28, 29
  472. {!"an ak-47" }, {!"an m4" }, {!"a tec-9" }, // 30, 31, 32
  473. {!"a cuntgun" }, {!"a sniper" }, {!"a rocketlauncher" }, // 33, 34, 35
  474. {!"a heatseeking rpg" }, {!"a flamethrower"}, {!"a minigun" }, // 36, 37, 38
  475. {!"a satchel" }, {!"a detonator" }, {!"a spraycan" }, // 39, 40, 41
  476. {!"an extinguisher" }, {!"a camera" }, {!"nightvision" }, // 42, 43, 44
  477. {!"an infrared" }, {!"a parachute" }, {!"a fake pistol" }, // 45, 46, 47
  478. {!"" }, {!"a vehicle" }, {!"a helikill" }, // , 49, 50
  479. {!"an explosion" }, {!"" }, {!"drowning" }, // 51, , 53
  480. {!"a collision" }, {!"a splat" }, {!"something unknown"} // 54, 55, 56
  481. }
  482. ;
  483.  
  484. if (0 <= weapon < sizeof(s_WeaponNamesLowercaseSingular))
  485. strcat(output, s_WeaponNamesLowercaseSingular[weapon]);
  486. else
  487. strcat(output, "something unknown");
  488. }
  489.  
  490. // Vehicle name
  491. formatSpecifier<'v'>(output[], modelid) {
  492.  
  493. static const
  494. s_VehicleNames[][] = {
  495. {!"Landstalker" }, {!"Bravura" }, {!"Buffalo" }, {!"Linerunner" },
  496. {!"Perrenial" }, {!"Sentinel" }, {!"Dumper" }, {!"Woz strazacki" },
  497. {!"Trashmaster" }, {!"Stretch" }, {!"Manana" }, {!"Infernus" },
  498. {!"Voodoo" }, {!"Pony" }, {!"Mule" }, {!"Cheetah" },
  499. {!"Ambulans" }, {!"Leviathan" }, {!"Moonbeam" }, {!"Esperanto" },
  500. {!"Taxi" }, {!"Washington" }, {!"Bobcat" }, {!"Mr Whoopee" },
  501. {!"BF Injection" }, {!"Hunter" }, {!"Premier" }, {!"Enforcer" },
  502. {!"Securicar" }, {!"Banshee" }, {!"Predator" }, {!"Bus" },
  503. {!"Czolg" }, {!"Barracks" }, {!"Hotknife" }, {!"Trailer 1" },
  504. {!"Previon" }, {!"Coach" }, {!"Cabbie" }, {!"Stallion" },
  505. {!"Rumpo" }, {!"RC Bandit" }, {!"Romero" }, {!"Packer" },
  506. {!"Monster" }, {!"Admiral" }, {!"Squalo" }, {!"Seasparrow" },
  507. {!"Pizzaboy" }, {!"Tramwaj" }, {!"Trailer 2" }, {!"Turismo" },
  508. {!"Speeder" }, {!"Reefer" }, {!"Tropic" }, {!"Flatbed" },
  509. {!"Yankee" }, {!"Caddy" }, {!"Solair" }, {!"Berkley's RC Van" },
  510. {!"Skimmer" }, {!"PCJ-600" }, {!"Faggio" }, {!"Freeway" },
  511. {!"RC Baron" }, {!"RC Raider" }, {!"Glendale" }, {!"Oceanic" },
  512. {!"Sanchez" }, {!"Sparrow" }, {!"Patriot" }, {!"Quad" },
  513. {!"Coastguard" }, {!"Dinghy" }, {!"Hermes" }, {!"Sabre" },
  514. {!"Rustler" }, {!"ZR-350" }, {!"Walton" }, {!"Regina" },
  515. {!"Comet" }, {!"BMX" }, {!"Burrito" }, {!"Camper" },
  516. {!"Marquis" }, {!"Baggage" }, {!"Dozer" }, {!"Maverick" },
  517. {!"News Chopper" }, {!"Rancher" }, {!"FBI Rancher" }, {!"Virgo" },
  518. {!"Greenwood" }, {!"Jetmax" }, {!"Hotring" }, {!"Sandking" },
  519. {!"Blista Compact" }, {!"Police Maverick" }, {!"Boxville" }, {!"Benson" },
  520. {!"Mesa" }, {!"RC Goblin" }, {!"Hotring Racer A" }, {!"Hotring Racer B" },
  521. {!"Bloodring Banger" }, {!"Rancher" }, {!"Super GT" }, {!"Elegant" },
  522. {!"Journey" }, {!"Rower" }, {!"Rower gorski" }, {!"Beagle" },
  523. {!"Cropdust" }, {!"Stunt" }, {!"Tanker" }, {!"Roadtrain" },
  524. {!"Nebula" }, {!"Majestic" }, {!"Buccaneer" }, {!"Shamal" },
  525. {!"Hydra" }, {!"FCR-900" }, {!"NRG-500" }, {!"Motor policyjny" },
  526. {!"Cement Truck" }, {!"Tow Truck" }, {!"Fortune" }, {!"Cadrona" },
  527. {!"Woz FBI" }, {!"Willard" }, {!"Forklift" }, {!"Traktor" },
  528. {!"Combine" }, {!"Feltzer" }, {!"Remington" }, {!"Slamvan" },
  529. {!"Blade" }, {!"Freight" }, {!"Streak" }, {!"Vortex" },
  530. {!"Vincent" }, {!"Bullet" }, {!"Clover" }, {!"Sadler" },
  531. {!"Woz strazacki" }, {!"Hustler" }, {!"Intruder" }, {!"Primo" },
  532. {!"Cargobob" }, {!"Tampa" }, {!"Sunrise" }, {!"Merit" },
  533. {!"Utility" }, {!"Nevada" }, {!"Yosemite" }, {!"Windsor" },
  534. {!"Monster A" }, {!"Monster B" }, {!"Uranus" }, {!"Jester" },
  535. {!"Sultan" }, {!"Stratum" }, {!"Elegy" }, {!"Raindance" },
  536. {!"RC Tiger" }, {!"Flash" }, {!"Tahoma" }, {!"Savanna" },
  537. {!"Bandito" }, {!"Freight Flat" }, {!"Lokomotywa" }, {!"Gokart" },
  538. {!"Mower" }, {!"Duneride" }, {!"Sweeper" }, {!"Broadway" },
  539. {!"Tornado" }, {!"AT-400" }, {!"DFT-30" }, {!"Huntley" },
  540. {!"Stafford" }, {!"BF-400" }, {!"Newsvan" }, {!"Tug" },
  541. {!"Trailer 3" }, {!"Emperor" }, {!"Wayfarer" }, {!"Euros" },
  542. {!"Hotdog" }, {!"Club" }, {!"Freight Carriage" }, {!"Trailer 3" },
  543. {!"Andromada" }, {!"Dodo" }, {!"RC Cam" }, {!"Launch" },
  544. {!"Radiowoz" }, {!"Radiowoz" }, {!"Radiowoz" }, {!"Police Ranger" },
  545. {!"Picador" }, {!"Pojazd S.W.A.T." }, {!"Alpha" }, {!"Phoenix" },
  546. {!"Glendale" }, {!"Sadler" }, {!"Luggage Trailer A"}, {!"Luggage Trailer B"},
  547. {!"Stair Trailer" }, {!"Boxville" }, {!"Farm Plow" }, {!"Utility Trailer" }
  548. }
  549. ;
  550.  
  551. if (0 <= (modelid -= 400) < sizeof(s_VehicleNames))
  552. strcat(output, s_VehicleNames[modelid]);
  553. else
  554. strcat(output, "Unknown");
  555. }
  556.  
  557. // Unsigned 4-byte hex
  558. formatSpecifier<'X'>(output[], value) {
  559. format(output, sizeof(output), "%02x%06x", value >>> 24, value & 0xFFFFFF);
  560. }
  561.  
  562. // Do this last so the specifiers always use the native function
  563. #if FORMAT_REPLACE_NATIVES
  564. #define format formatex
  565. #define printf printfex
Advertisement
Add Comment
Please, Sign In to add comment