WINDOWS.CPP 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: g:/library/source/rcs/./windows.c 1.12 1994/05/20 15:35:25 joe_bostic Exp $ */
  19. /***************************************************************************
  20. ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  21. ***************************************************************************
  22. * *
  23. * Project Name : LIBRARY *
  24. * *
  25. * File Name : WINDOWS.C *
  26. * *
  27. * Programmer : Everyone *
  28. * *
  29. * Last Update : February 3, 1992 [DRD] *
  30. * *
  31. *-------------------------------------------------------------------------*
  32. * Functions: *
  33. * Change_New_Window -- Combined Change_Window and New_Window. *
  34. * Change_Window -- Changes the 'current' window in the system. *
  35. * Fetch_Char -- Gets one undipthonged char from input. *
  36. * Flush_Line -- Outputs the accumulate text line to screen. *
  37. * In_Char -- Stores (un-dipped) character(s) from input to buffer. *
  38. * New_Window -- Clears the current window to the background color. *
  39. * Set_More_Off -- Turns the 'more' prompting off. *
  40. * Set_More_On -- Turns the 'more' prompting on. *
  41. * Set_More_Prompt -- Adjusts the more prompt text for default routine *
  42. * Standard_More_Prompt -- Default more prompt code for Window_Print *
  43. * Window_Int_Print -- Prints an integer to the window. *
  44. * Window_Print -- Displays and wraps text into a window. *
  45. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  46. #include <ctype.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <stdio.h>
  50. #include <stdarg.h>
  51. #include <wwstd.h>
  52. #include "ww_win.h"
  53. #include <keyboard.h>
  54. #include <font.h>
  55. #include <dipthong.h>
  56. PRIVATE void Scroll_Window(void);
  57. PRIVATE void Flush_Line(void);
  58. PRIVATE void In_Char(char *str);
  59. PRIVATE char Fetch_Char(void);
  60. PRIVATE int ScrollCounter = 0; // Count of the lines displayed before a pause.
  61. PRIVATE char Line[84]; // Staging line buffer.
  62. PRIVATE int Pos; // Char Position of next free character.
  63. PRIVATE int PPos; // Pixel position of next free character.
  64. PRIVATE int WPos; // Char position in window.
  65. PRIVATE char *MainSource;
  66. PRIVATE char *AltSource;
  67. PRIVATE char Char[2];
  68. PRIVATE char Stack;
  69. PRIVATE char WordWrapFlag = FALSE; // flag for a word wrap.
  70. PRIVATE int MoreSpace = 7;
  71. PRIVATE int MoreFColor = 0;
  72. PRIVATE int MoreBColor = 0;
  73. int WindowColumns=40;
  74. int WindowLines=25;
  75. int WindowWidth=40;
  76. unsigned int WinB=0;
  77. unsigned int WinC=1;
  78. unsigned int WinX=0;
  79. unsigned int WinY=0;
  80. unsigned int WinCx=0;
  81. unsigned int WinCy=0;
  82. unsigned int WinH=25;
  83. unsigned int WinW=40;
  84. unsigned int Window=0;
  85. int MoreOn = TRUE;
  86. char *TXT_MoreText = "--More--";
  87. void (*Window_More_Ptr)(char const *,int,int,int) = Standard_More_Prompt;
  88. extern GraphicViewPortClass *LogicPage;
  89. /***************************************************************************
  90. * STANDARD_MORE_PROMPT -- Default more prompt code for Window_Print *
  91. * *
  92. * This is the standard "<more>" prompting code that is used by *
  93. * Window_Print when a page is full of text and a pause is desired *
  94. * before the next page of text is printed. This function is called *
  95. * through the Window_More_Ptr global. *
  96. * *
  97. * INPUT: prompt -- Pointer to ASCII text that will be window printed *
  98. * at the right margin. *
  99. * *
  100. * space -- The number of spaces to allow for the 'more' text. *
  101. * *
  102. * fcolor -- The foreground color to use for the 'more' text. *
  103. * *
  104. * bcolor -- The background oclor to use for the 'more' text. *
  105. * *
  106. * OUTPUT: none *
  107. * *
  108. * WARNINGS: none *
  109. * *
  110. * HISTORY: *
  111. * 07/29/1991 JLB : Created. *
  112. *=========================================================================*/
  113. void Standard_More_Prompt(char const *prompt, int space, int fcolor, int bcolor)
  114. {
  115. int x, y, moresize;
  116. moresize = (space - 1) * (FontWidth+FontXSpacing);
  117. x = ((WinX+WinW) << 3) - moresize;
  118. //y = WinY + ((WinH/FontHeight)-1)*FontHeight;
  119. y = WinY + (WinCy-1) * (FontHeight+FontYSpacing);
  120. // Default "more" prompter.
  121. LogicPage->Print(prompt, x, y, fcolor ? fcolor : WindowList[Window][WINDOWBCOL], bcolor ? bcolor : WindowList[Window][WINDOWFCOL]);
  122. //BG if (LogicPage == SEENPAGE) {
  123. //BG Window_Show_Mouse();
  124. //BG }
  125. // PWG - have to figure out how to do this in windows library
  126. // Clear_KeyBuffer();
  127. // Get_Key();
  128. //BG if (LogicPage == SEENPAGE) {
  129. //BG Window_Hide_Mouse(Window);
  130. //BG }
  131. // Erase the more prompt prompt.
  132. // Text_Print(prompt, x, y, WinB, WinB);
  133. LogicPage->Fill_Rect(x, y, x + moresize - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB);
  134. }
  135. /***************************************************************************
  136. * SET_MORE_PROMPT -- Adjusts the more prompt text for default routine *
  137. * *
  138. * Use this routine to control the text of the "<MORE>" prompt that *
  139. * the default more prompt routine uses. This can be useful for *
  140. * foreign language translations. *
  141. * *
  142. * INPUT: prompt -- Pointer to ASCII text that will be window printed *
  143. * at the right margin. *
  144. * *
  145. * space -- The number of spaces to allow for the 'more' text. *
  146. * *
  147. * fcolor -- The foreground color to use for the 'more' text. *
  148. * *
  149. * bcolor -- The background color to use for the 'more' text. *
  150. * *
  151. * OUTPUT: none *
  152. * *
  153. * WARNINGS: none *
  154. * *
  155. * HISTORY: *
  156. * 07/29/1991 JLB : Created. *
  157. *=========================================================================*/
  158. void Set_More_Prompt(char const *prompt, int space, int fcolor, int bcolor)
  159. {
  160. if (prompt) {
  161. TXT_MoreText = (char*)prompt;
  162. MoreSpace = space;
  163. MoreFColor = fcolor;
  164. MoreBColor = bcolor;
  165. }
  166. else {
  167. TXT_MoreText = "<MORE>";
  168. MoreSpace = 7;
  169. MoreFColor = MoreBColor = 0;
  170. }
  171. }
  172. /***************************************************************************
  173. * SET_MORE_ON -- Turns the 'more' prompting on. *
  174. * *
  175. * Use this routine to turn on the 'more' prompting that Window_Print *
  176. * does. If you have a custom more function pointer, then that *
  177. * routine will be called, otherwise the library default 'more' prompt *
  178. * will be utilized. *
  179. * *
  180. * INPUT: none *
  181. * *
  182. * OUTPUT: none *
  183. * *
  184. * WARNINGS: none *
  185. * *
  186. * HISTORY: *
  187. * 07/25/1991 JLB : Created. *
  188. *=========================================================================*/
  189. void Set_More_On(void)
  190. {
  191. MoreOn = TRUE;
  192. ScrollCounter = 0;
  193. }
  194. /***************************************************************************
  195. * SET_MORE_OFF -- Turns the 'more' prompting off. *
  196. * *
  197. * This routine will turn the 'more' prompting that Window_Print does *
  198. * off. *
  199. * *
  200. * INPUT: none *
  201. * *
  202. * OUTPUT: none *
  203. * *
  204. * WARNINGS: none *
  205. * *
  206. * HISTORY: *
  207. * 07/25/1991 JLB : Created. *
  208. *=========================================================================*/
  209. void Set_More_Off(void)
  210. {
  211. MoreOn = FALSE;
  212. }
  213. /***************************************************************************
  214. * CHANGE_WINDOW -- Changes the 'current' window in the system. *
  215. * *
  216. * Use this routine to change the 'current' window. The current window *
  217. * is used in Window_Print and some other graphic output routines. *
  218. * *
  219. * INPUT: windnum -- The window number to change to. *
  220. * *
  221. * OUTPUT: Returns with the previously current window. *
  222. * *
  223. * WARNINGS: none *
  224. * *
  225. * HISTORY: *
  226. * 07/25/1991 JLB : Created. *
  227. *=========================================================================*/
  228. int Change_Window(int windnum)
  229. {
  230. int oldwindow;
  231. int *data;
  232. oldwindow = Window;
  233. Window = windnum;
  234. data = &WindowList[windnum][0];
  235. WinX = *data++;
  236. WinY = *data++;
  237. WinW = *data++;
  238. WinH = *data++;
  239. WinC = *data++;
  240. WinB = *data++;
  241. WinCx = *data++;
  242. WinCy = *data++;
  243. ScrollCounter = 0;
  244. WPos = WinCx / (FontWidth+FontXSpacing);
  245. WindowLines = (WinH-FontYSpacing) / (FontHeight+FontYSpacing);
  246. WindowWidth = WinW << 3;
  247. WindowColumns = WindowWidth / (FontWidth+FontXSpacing);
  248. return (oldwindow);
  249. }
  250. /***************************************************************************
  251. * CHANGE_NEW_WINDOW -- Combined Change_Window and New_Window. *
  252. * *
  253. * This is a combo-routine. It merely combines the Change_Window *
  254. * with the New_Window routines. It will save some (small) code if *
  255. * you use this routine instead of the two function calls. *
  256. * *
  257. * INPUT: window -- Window number to change to and clear. *
  258. * *
  259. * OUTPUT: Returns with the previously current window. *
  260. * *
  261. * WARNINGS: none *
  262. * *
  263. * HISTORY: *
  264. * 07/25/1991 JLB : Created. *
  265. *=========================================================================*/
  266. int Change_New_Window(int windnum)
  267. {
  268. int oldwindow;
  269. oldwindow = Change_Window(windnum);
  270. New_Window();
  271. return(oldwindow);
  272. }
  273. /***************************************************************************
  274. * NEW_WINDOW -- Clears the current window to the background color. *
  275. * *
  276. * This routine clears the current window to the background color. It *
  277. * is used in preparation to Window_Print because it ensures a clean *
  278. * 'slate' for the text. *
  279. * *
  280. * INPUT: none *
  281. * *
  282. * OUTPUT: none *
  283. * *
  284. * WARNINGS: none *
  285. * *
  286. * HISTORY: *
  287. * 07/25/1991 JLB : Created. *
  288. *=========================================================================*/
  289. void New_Window(void)
  290. {
  291. int x,y,w,h;
  292. x = WinX << 3;
  293. y = WinY;
  294. w = (WinX + WinW) << 3;
  295. h = WinY + WinH;
  296. LogicPage->Fill_Rect(x, y, w - 1, h - 1, (unsigned char)WinB);
  297. WinCx = WPos = 0;
  298. WinCy = 0;
  299. ScrollCounter = 0;
  300. }
  301. /***************************************************************************
  302. * WINDOW_INT_PRINT -- Prints an integer to the window. *
  303. * *
  304. * Use this routine to print an integer to the window. This routine *
  305. * as all other Window printing routines will handle word wrap. *
  306. * *
  307. * INPUT: num -- The integer to convert to ASCII and print. *
  308. * *
  309. * OUTPUT: none *
  310. * *
  311. * WARNINGS: none *
  312. * *
  313. * HISTORY: *
  314. * 07/25/1991 JLB : Created. *
  315. *=========================================================================*/
  316. void Window_Int_Print(int num)
  317. {
  318. Window_Print("%d", num);
  319. }
  320. /***************************************************************************
  321. * WINDOW_PRINT -- Displays and wraps text into a window. *
  322. * *
  323. * This is the general purpos text output routine that will handle *
  324. * word wrap within a window. It is useful for displaying arbitrary *
  325. * text. This routine will handle dipthonged text and as such it *
  326. * can be quite useful in saving memory. *
  327. * *
  328. * INPUT: string -- String to print. This can be of ANY length and *
  329. * can even contain some formatting codes. The *
  330. * codes supported are: *
  331. * *
  332. * KA_SETX Forces the cursor X position to the value *
  333. * specified. *
  334. * *
  335. * KA_SETY Forces the cursor Y position to the value *
  336. * specified. *
  337. * *
  338. * KA_MORE Causes an immediate "<MORE>" prompt *
  339. * regardless of the scroll situation. *
  340. * *
  341. * KA_RETURN Breaks line and continues output at the *
  342. * left edge of following line. *
  343. * *
  344. * *
  345. * KA_FORMFEED Clears the window and continues printing at *
  346. * the upper left corner. *
  347. * *
  348. * KA_SETBKGDCOL Set the background color with the color *
  349. * specified by the following byte. *
  350. * *
  351. * *
  352. * KA_SETFORECOL Set the foreground color with the color *
  353. * specified by the following byte. *
  354. * *
  355. * KA_TAB Move the cursor over to the next tabstop. *
  356. * Tabstops are set every 8 columns. *
  357. * *
  358. * KA_SPCTAB Insert spaces until the cursor is positioned *
  359. * at the next tabstop. *
  360. * *
  361. * %s Replace the "%s" with the text pointed to *
  362. * by the pointer argument passed to the *
  363. * routine (follows same method a printf). *
  364. * *
  365. * %d Replace the "%d" with an integer ASCII *
  366. * number of the int passed to the routine. *
  367. * *
  368. * OUTPUT: none *
  369. * *
  370. * WARNINGS: none *
  371. * *
  372. * HISTORY: *
  373. * 07/25/1991 JLB : Created. *
  374. * 07/29/1991 JLB : Added MORE, SETX, and SETY *
  375. *=========================================================================*/
  376. void Window_Print(char const string[], ...)
  377. {
  378. int oldcx, x, y; // Scratch variables.
  379. char c; // Current character.
  380. char buffer[10]; // Working %d buffer.
  381. int old_c, old_b; // Original window colors.
  382. va_list arg; // Argument list var.
  383. va_start(arg, string);
  384. WordWrapFlag = FALSE; // initialize word wrap flag.
  385. Pos = PPos = 0;
  386. Line[0] = '\0';
  387. Char[0] = Char[1] = 0;
  388. MainSource = (char*)&string[0];
  389. AltSource = NULL;
  390. old_c = WinC;
  391. old_b = WinB;
  392. //BG if (LogicPage == SEENPAGE) {
  393. //BG Window_Hide_Mouse(Window);
  394. //BG }
  395. while (TRUE) {
  396. c = Fetch_Char();
  397. if (!c) break; // Exit on NULL character.
  398. /*
  399. ** Substitution commands only work if not already expanding a
  400. ** string.
  401. */
  402. if (!AltSource) {
  403. if (c == '%') {
  404. switch(tolower(Char[0])) {
  405. case 's':
  406. AltSource = va_arg(arg, char*);
  407. if (AltSource) {
  408. Stack = Char[1];
  409. Char[0] = Char[1] = '\0';
  410. c = Fetch_Char();
  411. }
  412. break;
  413. case 'd':
  414. AltSource = buffer;
  415. sprintf(buffer, "%d", va_arg(arg, int));
  416. Stack = Char[1];
  417. Char[0] = Char[1] = '\0';
  418. c = Fetch_Char();
  419. break;
  420. default:
  421. break;
  422. }
  423. }
  424. }
  425. switch(c) {
  426. #if(FALSE)
  427. // these are the positions of foreign language characters
  428. /*
  429. ** These are characters that shouldn't be window printed because
  430. ** they are currently reserved.
  431. */
  432. case KA_CTRL_C:
  433. case KA_CTRL_D:
  434. case KA_CTRL_E:
  435. case KA_CTRL_G:
  436. case KA_CTRL_J:
  437. case KA_CTRL_K:
  438. case KA_CTRL_N:
  439. case KA_CTRL_O:
  440. case KA_CTRL_P:
  441. case KA_CTRL_Q:
  442. case KA_CTRL_R:
  443. case KA_CTRL_T:
  444. case KA_CTRL_U:
  445. case KA_CTRL_V:
  446. case KA_CTRL_W:
  447. case KA_CTRL_Z:
  448. case KA_CTRL_BACKSLASH:
  449. case KA_CTRL_CARROT:
  450. case KA_CTRL_UNDERLINE:
  451. break;
  452. #endif
  453. /*
  454. ** Force cursor column to specified X value.
  455. */
  456. case KA_SETX:
  457. Flush_Line();
  458. WPos = Fetch_Char();
  459. WPos = MAX(0, WPos);
  460. // WPos is max width char position
  461. WPos = MIN(WindowColumns-1, WPos);
  462. WinCx = WPos * (FontWidth+FontXSpacing);
  463. break;
  464. /*
  465. ** Force the cursor to specified Y value.
  466. */
  467. case KA_SETY:
  468. Flush_Line();
  469. WinCy = Fetch_Char();
  470. //WinCy = MAX(0, WinCy);
  471. WinCy = MIN((long)WindowLines-1, (long)WinCy);
  472. break;
  473. /*
  474. ** Force a "<MORE>" prompt.
  475. */
  476. case KA_MORE:
  477. Flush_Line();
  478. if (Window_More_Ptr) {
  479. //BG if (LogicPage == SEENPAGE) Window_Show_Mouse();
  480. Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor);
  481. //BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window);
  482. }
  483. break;
  484. /*
  485. ** Clear and home the window cursor. This is the same
  486. ** as New_Window().
  487. */
  488. case KA_FORMFEED:
  489. New_Window();
  490. break;
  491. /*
  492. ** Move cursor to start of next line.
  493. */
  494. case KA_RETURN:
  495. Flush_Line();
  496. ScrollCounter++;
  497. WinCx = 0;
  498. #if(FALSE)
  499. if (WinCy >= WindowLines-1) {
  500. Scroll_Window();
  501. }
  502. else {
  503. WinCy++;
  504. }
  505. #else
  506. WinCy++;
  507. #endif
  508. break;
  509. /*
  510. ** Set the background color.
  511. */
  512. case KA_SETBKGDCOL:
  513. Flush_Line();
  514. WinB = Fetch_Char();
  515. break;
  516. /*
  517. ** Set the foreground color.
  518. */
  519. case KA_SETFORECOL:
  520. Flush_Line();
  521. WinC = Fetch_Char();
  522. break;
  523. /*
  524. ** Move cursor to next column.
  525. */
  526. case KA_TAB:
  527. Flush_Line();
  528. WPos = ((WPos + 8) & 0xFFF8) - 1;
  529. if (WPos >= WindowColumns) {
  530. WPos = 0;
  531. }
  532. WinCx = WPos * (FontWidth+FontXSpacing);
  533. break;
  534. /*
  535. ** Tab to specified column but add spaces.
  536. */
  537. case KA_SPCTAB:
  538. Flush_Line();
  539. oldcx = WinCx;
  540. x = WinX << 3;
  541. y = WinY + (WinCy * (FontHeight+FontYSpacing));
  542. WPos = ((WPos + 8) & 0xFFF8) - 1;
  543. if (WPos >= WindowColumns) {
  544. WinCx = WPos = 0;
  545. // Fill_Rect instead of printing spaces
  546. LogicPage->Fill_Rect(x + oldcx, y,
  547. x + WindowWidth - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB);
  548. ScrollCounter++;
  549. WinCy++;
  550. }
  551. else {
  552. WinCx = WPos * (FontWidth+FontXSpacing);
  553. // Fill_Rect instead of printing spaces
  554. LogicPage->Fill_Rect(x + oldcx, y,
  555. x + WinCx - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB);
  556. }
  557. break;
  558. /*
  559. ** next character is a extended value 1-127, but 128 is added
  560. ** for a value 129-255
  561. */
  562. case KA_EXTEND:
  563. c = 127;
  564. // NOTE: this falls thru to the default case DO NOT MOVE!!!!!
  565. /*
  566. ** next character is a literal value 1-127, except 13
  567. */
  568. // case KA_LITERAL:
  569. // if (c != (char) 127) { // check if fell thru from extend case
  570. // c = 0; // set to zero for literal case
  571. // }
  572. // c += Fetch_Char();
  573. // NOTE: this falls thru to the default case DO NOT MOVE!!!!!
  574. /*
  575. ** Normal character output.
  576. */
  577. default:
  578. PPos += Char_Pixel_Width(c); // get pixel location of next char
  579. Line[Pos++] = c;
  580. Line[Pos] = '\0';
  581. if (WinCx + PPos > WindowWidth) {
  582. Flush_Line();
  583. }
  584. break;
  585. }
  586. }
  587. /*
  588. ** If there is text still pending, then display it before exiting.
  589. */
  590. if (Pos) Flush_Line();
  591. /*
  592. ** Record changes in the cursor position.
  593. */
  594. WindowList[Window][WINDOWCURSORX] = WinCx;
  595. WindowList[Window][WINDOWCURSORY] = WinCy;
  596. /*
  597. ** Restore the window colors to their original values.
  598. */
  599. WindowList[Window][WINDOWFCOL] = WinC = old_c;
  600. WindowList[Window][WINDOWBCOL] = WinB = old_b;
  601. //BG if (LogicPage == SEENPAGE) {
  602. //BG Window_Show_Mouse();
  603. //BG }
  604. va_end(arg);
  605. }
  606. /***************************************************************************
  607. * SCROLL_WINDOW -- Scrolls the text window up one line. *
  608. * *
  609. * This will scroll the text window up one line. It will handle any *
  610. * pausing for "more" if the MoreOn flag is set. *
  611. * *
  612. * INPUT: none *
  613. * *
  614. * OUTPUT: none *
  615. * *
  616. * WARNINGS: This routine assumes that the LogicPage is the SEENPAGE. *
  617. * If this is not the case, the program may appear to hang *
  618. * if a "more" prompt is generated. *
  619. * *
  620. * HISTORY: *
  621. * 07/25/1991 JLB : Created. *
  622. *=========================================================================*/
  623. PRIVATE void Scroll_Window(void)
  624. {
  625. int y; // Top pixel row of bottom line of window.
  626. /*
  627. ** Possibly prompt for more text.
  628. */
  629. if (ScrollCounter >= WindowLines-1 && MoreOn) {
  630. ScrollCounter = 0;
  631. if (Window_More_Ptr) {
  632. //BG if (LogicPage == SEENPAGE) Window_Show_Mouse();
  633. Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor);
  634. //BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window);
  635. }
  636. }
  637. /*
  638. ** Scroll the window up one line.
  639. */
  640. y = ((WinH / (FontHeight+FontYSpacing)) - 1) * (FontHeight+FontYSpacing);
  641. LogicPage->Blit(*LogicPage,WinX<<3, WinY + (FontHeight+FontYSpacing), WinX<<3, WinY, WinW<<3, WinH - (FontHeight+FontYSpacing) );
  642. LogicPage->Fill_Rect(WinX<<3,
  643. WinY + y,
  644. ((WinX+WinW)<<3) - 1,
  645. WinY + WinH - 1,
  646. (unsigned char)WinB);
  647. }
  648. /***************************************************************************
  649. * FLUSH_LINE -- Outputs the accumulate text line to screen. *
  650. * *
  651. * This will display the accumlated text line to the screen. It will *
  652. * handle breaking the text line at an appropriate position. *
  653. * *
  654. * INPUT: none *
  655. * *
  656. * OUTPUT: none *
  657. * *
  658. * WARNINGS: none *
  659. * *
  660. * HISTORY: *
  661. * 07/25/1991 JLB : Created. *
  662. *=========================================================================*/
  663. PRIVATE void Flush_Line(void)
  664. {
  665. int breakit, breaksize, breakwidth;
  666. int x, y; // Coordinates of text print.
  667. int breakpoint; // Point to break the line (if possible).
  668. char breakchar; // Break replace character.
  669. int index; // Backward moving index var.
  670. /*
  671. ** There could be a held <CR> and this is implied by the cursor Y position
  672. ** beyond the bottom of the window. If this is the case, then scroll the
  673. ** window and proceed with the line flush.
  674. */
  675. while (WinCy >= WindowLines /*&& Pos > 0*/) {
  676. Scroll_Window();
  677. if (WinCy >= WindowLines) WinCy--;
  678. }
  679. //if (WinCy >= WindowLines) WinCy = WindowLines-1;
  680. x = (WinX<<3) + WinCx;
  681. y = WinY + (WinCy*(FontHeight+FontYSpacing));
  682. breakwidth = WindowWidth;
  683. // if (ScrollCounter >= WindowLines - 1 && MoreOn) {
  684. // breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width
  685. // }
  686. /*
  687. ** Try to break the line at the last space IF the line has reached the edge
  688. ** of the window.
  689. */
  690. breakpoint = Pos;
  691. breaksize = PPos;
  692. if (WinCx + breaksize > breakwidth) {
  693. /*
  694. ** Since the text WILL spill past the edge of the window, determine the
  695. ** point where the break should occur. If this line is ready for the <MORE>
  696. ** prompt, then breaking must account for the <MORE> text.
  697. */
  698. if (ScrollCounter >= WindowLines - 1 && MoreOn) {
  699. breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width
  700. }
  701. breakwidth -= WinCx;
  702. breakit = 0;
  703. for (index = breakpoint - 1; index > 0; index--) {
  704. breakchar = Line[index];
  705. breaksize -= Char_Pixel_Width(breakchar);
  706. // only once, find largest text that can fit on the line
  707. if (!breakit) {
  708. // was this the char that went past the right edge
  709. if (breaksize <= breakwidth) {
  710. breakit = index; // save this position if there is no spaces
  711. }
  712. }
  713. // after largest text is found then look for a space to break on
  714. if (breakit && breakchar == KA_SPACE) {
  715. breakpoint = index;
  716. WordWrapFlag = FALSE; // word will start at beginning of next line
  717. break;
  718. }
  719. }
  720. /*
  721. ** Exception: When the current text buffer cannot be broken at a logical
  722. ** place AND the text is starting past the left margin, THEN there is
  723. ** an implied break between the previous text output and this one.
  724. ** Output the current text on the next line left margin.
  725. */
  726. if (!index) {
  727. if (WinCx && !WordWrapFlag) {
  728. breakpoint = breaksize = 0; // Continue text on next line.
  729. WordWrapFlag = TRUE; // indicate a word continuation.
  730. }
  731. else {
  732. breakpoint = breakit; // Just print as much as possible.
  733. }
  734. }
  735. }
  736. breakchar = Line[breakpoint];
  737. Line[breakpoint] = '\0';
  738. LogicPage->Print(Line, x, y, WinC, WinB);
  739. WinCx += breaksize; // add size of text string printed.
  740. Line[breakpoint] = breakchar;
  741. if (breakchar == KA_SPACE) { // take out a space between words.
  742. breakpoint++;
  743. }
  744. // take out another space for double spacing after end of sentence.
  745. if (Line[breakpoint] == KA_SPACE) {
  746. breakpoint++;
  747. }
  748. strcpy(Line, &Line[breakpoint]);
  749. Pos = strlen(Line);
  750. PPos = String_Pixel_Width(Line);
  751. /*
  752. ** If at this point there is still text in the buffer, then flushing has
  753. ** not been completed. Scroll to next line and repeat the text flushing
  754. ** process.
  755. */
  756. if (Pos || WinCx >= WindowWidth) {
  757. WinCx = WPos = 0;
  758. #if(FALSE)
  759. if (WinCy >= WindowLines-1) {
  760. Scroll_Window();
  761. } else {
  762. WinCy++;
  763. }
  764. #else
  765. WinCy++;
  766. #endif
  767. Flush_Line();
  768. ScrollCounter++; // must be done after flush line for correct counting
  769. }
  770. }
  771. /***************************************************************************
  772. * IN_CHAR -- Stores (un-dipped) character(s) from input to buffer. *
  773. * *
  774. * Use this routine to fetch the next character from the input stream. *
  775. * If the character was dipthonged, then it will be broken into its *
  776. * component ASCII characters and stored in the specified location. *
  777. * This is the core character stream reading code. *
  778. * *
  779. * INPUT: str -- char pointer to the position to store the character(s)*
  780. * fetched from the input stream. *
  781. * *
  782. * OUTPUT: none *
  783. * *
  784. * WARNINGS: none *
  785. * *
  786. * HISTORY: *
  787. * 07/25/1991 JLB : Created. *
  788. *=========================================================================*/
  789. PRIVATE void In_Char(char *str)
  790. {
  791. char c; // Character to return.
  792. char next; // Following character (if any).
  793. c = next = '\0';
  794. /*
  795. ** Fetch a raw byte from the input stream.
  796. */
  797. if (AltSource) {
  798. if (*AltSource == '\0') {
  799. AltSource = NULL;
  800. c = Stack;
  801. } else {
  802. c = *AltSource++;
  803. }
  804. }
  805. if (!c && MainSource) {
  806. if (*MainSource == '\0') {
  807. MainSource = NULL;
  808. } else {
  809. c = *MainSource++;
  810. }
  811. }
  812. /*
  813. ** Convert a dipthong character into it's component
  814. ** ASCII characters.
  815. */
  816. if (c & 0x80) {
  817. c &= 0x7F;
  818. next = c & (char)0x07;
  819. c = (char)((c & (char)0x78) >> 3);
  820. next = Dipthong[c][next]; // Dipthong character.
  821. c = Common[c]; // Common character.
  822. }
  823. *str++ = c;
  824. *str = next;
  825. }
  826. /***************************************************************************
  827. * FETCH_CHAR -- Gets one undipthonged char from input. *
  828. * *
  829. * This routine will fetch one character from the input stream. The *
  830. * character has already been un-dipthonged. It is a straight ASCII *
  831. * character. This routine ensures that if the next character in the *
  832. * input stream needs to be examined, it is available in Char[0]. *
  833. * *
  834. * INPUT: none *
  835. * *
  836. * OUTPUT: Returns next character in the input stream (ASCII). If NULL *
  837. * is returned, then this indicates the end of the input stream. *
  838. * *
  839. * WARNINGS: none *
  840. * *
  841. * HISTORY: *
  842. * 07/25/1991 JLB : Created. *
  843. *=========================================================================*/
  844. PRIVATE char Fetch_Char(void)
  845. {
  846. char c; // Character to return.
  847. if (!Char[0]) {
  848. In_Char(&Char[0]);
  849. }
  850. c = Char[0];
  851. Char[0] = Char[1];
  852. Char[1] = '\0';
  853. if (!Char[0]) {
  854. In_Char(&Char[0]);
  855. }
  856. return (c);
  857. }
  858.