Guest User

formatex.inc by Slice

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