Advertisement
dominus

Untitled

Feb 10th, 2025
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 9.53 KB | None | 0 0
  1. diff --git a/gumps/Book_gump.cc b/gumps/Book_gump.cc
  2. index 3e7da65bb..daed28bad 100644
  3. --- a/gumps/Book_gump.cc
  4. +++ b/gumps/Book_gump.cc
  5. @@ -40,7 +40,7 @@ void Book_gump::paint() {
  6.     // Paint the gump itself.
  7.     paint_shape(x, y);
  8.     // Paint left page.
  9. -   curend = paint_page(TileRect(36, 10, 122, 130), curtop);
  10. +   curend = paint_page(TileRect(35, 8, 125, 132), curtop);
  11.     // Paint right page.
  12. -   curend = paint_page(TileRect(174, 10, 122, 130), curend);
  13. +   curend = paint_page(TileRect(173, 8, 125, 132), curend);
  14.  }
  15. diff --git a/gumps/Scroll_gump.cc b/gumps/Scroll_gump.cc
  16. index 533f4f49b..f66837026 100644
  17. --- a/gumps/Scroll_gump.cc
  18. +++ b/gumps/Scroll_gump.cc
  19. @@ -39,5 +39,5 @@ Scroll_gump::Scroll_gump(int fnt, int gump)
  20.  void Scroll_gump::paint() {
  21.     // Paint the gump itself.
  22.     paint_shape(x, y);
  23. -   curend = paint_page(TileRect(52, 30, 142, 118), curtop);
  24. +   curend = paint_page(TileRect(51, 31, 142, 118), curtop);
  25.  }
  26. diff --git a/gumps/Text_gump.cc b/gumps/Text_gump.cc
  27. index 5feb93b07..5f3032c26 100644
  28. --- a/gumps/Text_gump.cc
  29. +++ b/gumps/Text_gump.cc
  30. @@ -21,10 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  31.  #endif
  32.  
  33.  #include "Text_gump.h"
  34. -
  35. +#include "game.h"
  36.  #include "gamewin.h"
  37.  
  38.  #include <cstring>
  39. +#include <string>
  40.  
  41.  using std::strchr;
  42.  
  43. @@ -33,21 +34,18 @@ using std::strchr;
  44.   */
  45.  
  46.  void Text_gump::add_text(const char* str) {
  47. -   const int slen = strlen(str);    // Length of new text.
  48. -   // Allocate new space.
  49. -   char* newtext = new char[textlen + (textlen != 0) + slen + 1];
  50. -   if (textlen) {    // Copy over old.
  51. -       strcpy(newtext, text);
  52. -       // Add new line if not starting a new page and if first char of new
  53. -       // string is not a new line
  54. +   std::string newtext;
  55. +   if (textlen) {
  56. +       newtext = text;
  57.         if (newtext[textlen - 1] != '*') {
  58. -           newtext[textlen++] = '~';
  59. +           newtext += '~';
  60.         }
  61.     }
  62. -   strcpy(newtext + textlen, str);    // Append new.
  63. +   newtext += str;
  64.     delete[] text;
  65. -   text = newtext;
  66. -   textlen += slen;
  67. +   text = new char[newtext.length() + 1];
  68. +   strcpy(text, newtext.c_str());
  69. +   textlen = newtext.length();
  70.  }
  71.  
  72.  /*
  73. @@ -56,50 +54,185 @@ void Text_gump::add_text(const char* str) {
  74.   *  Output: Index past end of displayed page.
  75.   */
  76.  
  77. -int Text_gump::paint_page(
  78. -       const TileRect& box,     // Display box rel. to gump.
  79. -       int             start    // Starting offset into text.
  80. -) {
  81. -   const int vlead      = 1;    // Extra inter-line spacing.
  82. +int Text_gump::paint_page(const TileRect& box, int start) {
  83.     int       ypos       = 0;
  84. +   const int vlead      = 1;
  85.     const int textheight = sman->get_text_height(font) + vlead;
  86.     char*     str        = text + start;
  87. -   while (*str && *str != '*' && ypos + textheight <= box.h) {
  88. -       if (*str == '~') {    // Empty paragraph?
  89. -           ypos += textheight;
  90. -           str++;
  91. -           continue;
  92. +   curend = start;    // Initialize curend to the starting position
  93. +
  94. +   char* lineBreak     = nullptr;
  95. +   char* pageBreakStar = nullptr;
  96. +   char* extraBreak    = nullptr;
  97. +   char* epage         = nullptr;    // page break marker
  98. +   char* eol           = nullptr;    // end-of-line marker
  99. +
  100. +   while (*str && ypos + textheight <= box.h) {
  101. +       // Find the first tilde (line break marker)
  102. +       lineBreak = strchr(str, '~');
  103. +       // Update markers based on current position
  104. +       pageBreakStar = strchr(str, '*');
  105. +
  106. +       if (GAME_SI) {
  107. +           extraBreak = strstr(str, "~~~");
  108. +       }
  109. +       if (GAME_BG) {
  110. +           extraBreak = strstr(str, " ~~");
  111. +           if (extraBreak) {
  112. +               // If " ~~" is preceded by "~~", ignore it.
  113. +               if (extraBreak - text >= 2 && *(extraBreak - 2) == '~'
  114. +                   && *(extraBreak - 1) == '~') {
  115. +                   extraBreak = nullptr;
  116. +               }
  117. +           }
  118.         }
  119. -       // Look for page break.
  120. -       char* epage = strchr(str, '*');
  121. -       // Look for line break.
  122. -       char* eol = strchr(str, '~');
  123. -       if (epage && (!eol || eol > epage)) {
  124. -           eol = epage;
  125. +
  126. +       // if extraBreak is found and it occurs at the same position
  127. +       //  as the first tilde, use it as page break.
  128. +       if (extraBreak && lineBreak
  129. +           && ((GAME_SI && extraBreak == lineBreak)
  130. +               || (GAME_BG && extraBreak + 1 == lineBreak))) {
  131. +           epage = extraBreak;
  132. +           eol   = extraBreak;
  133. +       } else if (pageBreakStar && (!lineBreak || pageBreakStar < lineBreak)) {
  134. +           epage = pageBreakStar;
  135. +           eol   = pageBreakStar;
  136. +       } else {
  137. +           eol   = lineBreak;
  138. +           epage = nullptr;    // no page break marker
  139.         }
  140. -       if (!eol) {    // No end found?
  141. +
  142. +       if (!eol) {
  143. +           // No marker found: paint until the end of text.
  144.             eol = text + textlen;
  145.         }
  146. -       const char eolchr = *eol;    // Save char. at EOL.
  147. -       *eol              = 0;
  148. -       const int endoff  = sman->paint_text_box(
  149. -                font, str, x + box.x, y + box.y + ypos, box.w, box.h - ypos,
  150. -                vlead);
  151. -       *eol = eolchr;       // Restore char.
  152. -       if (endoff > 0) {    // All painted?
  153. -           // Value returned is height.
  154. -           str = eol + (eolchr == '~');
  155. +
  156. +       // Temporarily null-terminate at eol for painting.
  157. +       const char eolchr = *eol;
  158. +       *eol              = '\0';
  159. +
  160. +       int endoff = sman->paint_text_box(
  161. +               font, str, x + box.x, y + box.y + ypos, box.w, box.h - ypos,
  162. +               vlead);
  163. +       // Restore the character at eol.
  164. +       *eol = eolchr;
  165. +
  166. +       if (endoff > 0) {
  167. +           // Check for a page‑break marker
  168. +           if (epage) {
  169. +               // Handle extraBreak marker (e.g. "~~~" or " ~~")
  170. +               if (extraBreak && epage == extraBreak) {
  171. +                   if (GAME_SI && start == 0 && ypos == 0) {
  172. +                       // If it's the first line of the entire text, ignore the
  173. +                       // extraBreak
  174. +                       eol    = extraBreak + 1;
  175. +                       str    = eol;
  176. +                       curend = str - text;
  177. +                       ypos += endoff;
  178. +                       continue;
  179. +                   }
  180. +                   // Calculate vertical space remaining after the current
  181. +                   // block has been painted.
  182. +                   int remaining = box.h - (ypos + endoff);
  183. +
  184. +                   // Require room for at least two extra full line.
  185. +                   if (remaining >= 2 * textheight) {
  186. +                       // Reserve two extra line for spacing; the rest is
  187. +                       // available for the next text chunk.
  188. +                       int available = remaining - (2 * textheight);
  189. +                       if (available < 0) {
  190. +                           available = 0;
  191. +                       }
  192. +
  193. +                       // Use existing markers to find earliest upcoming marker
  194. +                       const char* earliest
  195. +                               = text + textlen;    // default: measure to
  196. +                                                    // end-of-text
  197. +
  198. +                       if (pageBreakStar > eol + 3
  199. +                           && pageBreakStar < earliest) {
  200. +                           earliest = pageBreakStar;
  201. +                       }
  202. +                       if (extraBreak > eol + 3 && extraBreak < earliest) {
  203. +                           earliest = extraBreak;
  204. +                       }
  205. +
  206. +                       // Temporarily replace the character at 'earliest' with
  207. +                       // '\0' to isolate the next chunk.
  208. +                       char saved = *earliest;
  209. +
  210. +                       // PEEK MEASUREMENT:
  211. +                       // To avoid drawing on top of already painted text, we
  212. +                       // use an off-screen y coordinate (e.g. -1000).
  213. +                       int peekHeight = sman->paint_text_box(
  214. +                               font,
  215. +                               eol + 3,    // start after extraBreak marker
  216. +                               x + box.x,
  217. +                               -1000,    // off-screen y coordinate for
  218. +                                         // measurement only
  219. +                               box.w, available, vlead);
  220. +                       // Restore the character we replaced.
  221. +                       *((char*)earliest) = saved;
  222. +
  223. +                       if (peekHeight > 0
  224. +                           && peekHeight
  225. +                                      <= available + 5)    // Add a tolerance
  226. +                                                           // of 5 pixels
  227. +                       {
  228. +                           // The entire upcoming text fits in the available
  229. +                           // space. Consume the extraBreak marker and add an
  230. +                           // extra line spacing.
  231. +                           eol += 1;    // skip extraBreak marker ("~~~" or "
  232. +                                        // ~~")
  233. +                           ypos += endoff;    // update vertical offset
  234. +                           str = eol;    // continue painting after the marker
  235. +                           curend = str - text;    // Update curend
  236. +                           continue;    // next iteration: the peeked block
  237. +                                        // will be painted on this page only
  238. +                       } else {
  239. +                           // The upcoming block does not fully fit;
  240. +                           // consume the marker and break so that it will be
  241. +                           // painted on the next page.
  242. +                           eol += 3;
  243. +                           str    = eol;
  244. +                           curend = str - text;    // Update curend
  245. +                           break;
  246. +                       }
  247. +                   }
  248. +               }
  249. +           } else if (eolchr == '~' || (lineBreak && lineBreak == eol)) {
  250. +               // Normal handling for a tilde line break.
  251. +               eol++;
  252. +           }
  253. +
  254. +           // After handling markers (or if none applied), update the text
  255. +           // pointer and vertical offset.
  256.             ypos += endoff;
  257. -       } else {    // Out of room.
  258. +           str    = eol;
  259. +           curend = str - text;    // Update curend
  260. +
  261. +           // Skip any leading space at the beginning of a new line.
  262. +           if (*str == ' ') {
  263. +               str++;
  264. +           }
  265. +       } else {
  266. +           // Out of room or partial paint -> back up
  267.             str += -endoff;
  268. +           curend = str - text;    // Update curend
  269.             break;
  270.         }
  271.     }
  272. -   if (*str == '*') {    // Saw end of page?
  273. -       str++;
  274. +
  275. +   // After the loop, check for markers at current position
  276. +   if (GAME_SI && extraBreak && extraBreak == str) {
  277. +       str += 3;    // skip "~~~"
  278. +   } else if (pageBreakStar && pageBreakStar == str) {
  279. +       str++;    // skip "*"
  280.     }
  281. -   gwin->set_painted();    // Force blit.
  282. -   return str - text;      // Return offset past end.
  283. +
  284. +   curend = str - text;    // Update curend one last time after the loop
  285. +   gwin->set_painted();
  286. +   return str - text;
  287.  }
  288.  
  289.  /*
  290. @@ -113,6 +246,12 @@ int Text_gump::show_next_page() {
  291.         return 0;    // That's all, folks.
  292.     }
  293.     curtop = curend;    // Start next page or pair of pages.
  294. -   paint();            // Paint.  This updates curend.
  295. +
  296. +   // Skip any leading tildes at the beginning of the new page.
  297. +   while (curtop < textlen && text[curtop] == '~') {
  298. +       curtop++;
  299. +   }
  300. +
  301. +   paint();    // Paint.  This updates curend.
  302.     return 1;
  303.  }
  304.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement