WINDOWS.CPP 37 KB

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