Advertisement
Guest User

Untitled

a guest
Mar 26th, 2011
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.65 KB | None | 0 0
  1. #define BYTES_PER_CELL (4)
  2. // HUGE credit to ZeeX for finally cracking this problem:
  3. // [url=http://forum.sa-mp.com/index.php?topic=79810.msg901721#msg901721]http://forum.sa-mp.com/index.php?topic=79810.msg901721#msg901721[/url]
  4. stock CPF(playerid, color, fstring[], {Float, _}:...)
  5. {
  6. // This is the number of parameters which are not variable that are passed
  7. // to this function (i.e. the number of named parameters).
  8. static const
  9. STATIC_ARGS = 3;
  10. // Get the number of variable arguments.
  11. new
  12. n = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
  13. if (n)
  14. {
  15. new
  16. message[128],
  17. arg_start,
  18. arg_end;
  19.  
  20. // Load the real address of the last static parameter. Do this by
  21. // loading the address of the last known static parameter and then
  22. // adding the value of [FRM].
  23. #emit CONST.alt fstring
  24. #emit LCTRL 5
  25. #emit ADD
  26. #emit STOR.S.pri arg_start
  27.  
  28. // Load the address of the last variable parameter. Do this by adding
  29. // the number of variable parameters on the value just loaded.
  30. #emit LOAD.S.alt n
  31. #emit ADD
  32. #emit STOR.S.pri arg_end
  33.  
  34. // Push the variable arguments. This is done by loading the value of
  35. // each one in reverse order and pushing them. I'd love to be able to
  36. // rewrite this to use the values of pri and alt for comparison,
  37. // instead of having to constantly load and reload two variables.
  38. #emit LOAD.S.alt arg_start
  39. ARG_CHECK_LOOP:
  40. //do
  41. //{
  42. #emit LOAD.I
  43. #emit PUSH.pri
  44. arg_end -= BYTES_PER_CELL;
  45. #emit LOAD.S.pri arg_end
  46. #emit JLEQ ARG_CHECK_LOOP
  47. //}
  48. //while (arg_end > arg_start);
  49.  
  50. // Push the static format parameters.
  51. #emit PUSH.S fstring
  52. #emit PUSH.C 128
  53. #emit PUSH.ADR message
  54.  
  55. // Now push the number of arguments passed to format, including both
  56. // static and variable ones and call the function.
  57. n += BYTES_PER_CELL * 3;
  58. #emit PUSH.S n
  59. #emit SYSREQ.C format
  60.  
  61. // Remove all data, including the return value, from the stack.
  62. n += BYTES_PER_CELL;
  63. #emit LCTRL 4
  64. #emit LOAD.S.alt n
  65. #emit ADD
  66. #emit SCTRL 4
  67.  
  68. //return SendClientMessage(playerid, color, message);
  69. return print(message);
  70. }
  71. else
  72. {
  73. //return SendClientMessage(playerid, color, fstring);
  74. return print(fstring);
  75. }
  76. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement