WINDOWS.CPP.BAK 37 KB

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