renderer2.inc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // y_text renderer v2.
  2. // This new version embeds linked lists for each item of interest in the strings
  3. // to iterate over one at a time. The items of interest are (currently):
  4. //
  5. // - SA:MP format specifiers.
  6. // - Custom (YSI) format specifiers.
  7. // - Colours.
  8. // - Line breaks.
  9. //
  10. // The formats for each are below.
  11. #define Y_TEXT_STATIC
  12. static stock TextR_GetNext(string:str[], pos)
  13. {
  14. }
  15. enum E_TEXT_RENDER_PASSES
  16. {
  17. E_TEXT_RENDER_PASS_ALL = -1,
  18. E_TEXT_RENDER_PASS_NATIVE,
  19. E_TEXT_RENDER_PASS_CUSTOM,
  20. E_TEXT_RENDER_PASS_COLOUR,
  21. E_TEXT_RENDER_PASS_NEWLINE
  22. }
  23. enum e_TEXT_RENDER
  24. {
  25. e_TEXT_RENDER_NEXT_MASK = 0x00FFFFFF,
  26. e_TEXT_RENDER_NEXT_SHIFT = 0,
  27. e_TEXT_RENDER_TYPE_MASK = 0xFF000000,
  28. e_TEXT_RENDER_TYPE_SHIFT = 24
  29. }
  30. enum e_TEXT_RENDER_SAMP
  31. {
  32. // The basic types (%x etc).
  33. e_TEXT_RENDER_SAMP_TYPE_MASK = 0xE0000000,
  34. e_TEXT_RENDER_SAMP_TYPE_SHIFT = 29,
  35. e_TEXT_RENDER_SAMP_TYPE_b = 0x20000000,
  36. e_TEXT_RENDER_SAMP_TYPE_c = 0x40000000,
  37. e_TEXT_RENDER_SAMP_TYPE_di = 0x60000000,
  38. e_TEXT_RENDER_SAMP_TYPE_f = 0x80000000,
  39. e_TEXT_RENDER_SAMP_TYPE_hx = 0xA0000000,
  40. e_TEXT_RENDER_SAMP_TYPE_s = 0xC0000000,
  41. // Weight (%5s etc).
  42. e_TEXT_RENDER_SAMP_WEIGHT_MASK = 0x00FFF000,
  43. e_TEXT_RENDER_SAMP_WEIGHT_SHIFT = 12,
  44. // Precision (%.5s etc).
  45. e_TEXT_RENDER_SAMP_PREC_MASK = 0x00000FFF,
  46. e_TEXT_RENDER_SAMP_PREC_SHIFT = 0,
  47. // Additional flags (%0*f etc).
  48. e_TEXT_RENDER_SAMP_FLAG_MASK = 0x1F000000,
  49. e_TEXT_RENDER_SAMP_FLAG_SHIFT = 24,
  50. e_TEXT_RENDER_SAMP_FLAG_0PAD = 0x01000000,
  51. e_TEXT_RENDER_SAMP_FLAG_WEIGHT = 0x02000000,
  52. e_TEXT_RENDER_SAMP_FLAG_PREC = 0x04000000,
  53. e_TEXT_RENDER_SAMP_FLAG_WSTAR = 0x08000000,
  54. e_TEXT_RENDER_SAMP_FLAG_PSTAR = 0x10000000
  55. }
  56. /**
  57. <remarks>
  58. While processing a string, we maintain multiple linked lists, each one
  59. holding the formatting locations for different passes. There are several
  60. passes of the data:
  61. 1) SA:MP formatting - Does all the standard format specifiers (%d etc).
  62. 2) YSI formatting - Does custom specifiers like "%n".
  63. 4) Colours - Fades require the full text, so come after formatting.
  64. 3) Newlines - Determine how (if) to split the string up.
  65. The colours coming before the newlines is a little awkward, but so is the
  66. other way around. I think I might actually need a new way of doing it that
  67. extracts the newline linked list before doing colours, but then the tested
  68. TextR_UpdatePass function can't be used... Were that to be done though, the
  69. newline linked list would be extracted, colours would be done simply, while
  70. updating the newline linked list, then renders would be done last. In fact,
  71. newlines should probably be part of the "render" pass.
  72. </remarks>
  73. **/
  74. Y_TEXT_STATIC stock TextR_UpdatePass(string:str[], indexes[E_TEXT_RENDER_PASSES], addition, nextPos, E_TEXT_RENDER_PASSES:pass)
  75. {
  76. // "pass" is not defined here in "for" so we can skip early passes in the
  77. // update code after they have already been run. The calling code passes
  78. // the CURRENT pass, which is instantly incremented.
  79. while (++pass != E_TEXT_RENDER_PASSES)
  80. {
  81. new
  82. cur = indexes[pass];
  83. if (cur > nextPos)
  84. {
  85. // Also covers cases where there are none left.
  86. indexes[pass] += addition;
  87. }
  88. else
  89. {
  90. // Add the length of the string just formatted (-2) to the offset to
  91. // the next action of the current pass in this string. Get the new
  92. // relative offset to the next item.
  93. new
  94. off = (str[cur] += addition) & e_TEXT_RENDER_NEXT_MASK;
  95. // Find the absolute position of the next item, then test if it is
  96. // before "nextPos" (not <=).
  97. while ((cur += off) < nextPos)
  98. {
  99. if ((off = str[cur] & e_TEXT_RENDER_NEXT_MASK))
  100. {
  101. indexes[pass] = cur;
  102. }
  103. else
  104. {
  105. // There are no actions of this rendering pass after
  106. // "nextPos" in the string.
  107. indexes[pass] = 65536;
  108. break;
  109. }
  110. }
  111. }
  112. }
  113. }
  114. enum E_TEXT_RENDER_SAMP
  115. {
  116. E_TEXT_RENDER_SAMP_NEXT,
  117. e_TEXT_RENDER_SAMP:E_TEXT_RENDER_SAMP_TYPE
  118. }
  119. //