Advertisement
dominus

Untitled

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