Subversion Repositories Kolibri OS

Rev

Rev 9097 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. // WL_TEXT.C
  2.  
  3. #include "wl_def.h"
  4. #pragma hdrstop
  5.  
  6. /*
  7. =============================================================================
  8.  
  9. TEXT FORMATTING COMMANDS
  10. ------------------------
  11. ^C<hex digit>           Change text color
  12. ^E[enter]               End of layout (all pages)
  13. ^G<y>,<x>,<pic>[enter]  Draw a graphic and push margins
  14. ^P[enter]               start new page, must be the first chars in a layout
  15. ^L<x>,<y>[ENTER]        Locate to a specific spot, x in pixels, y in lines
  16.  
  17. =============================================================================
  18. */
  19.  
  20. /*
  21. =============================================================================
  22.  
  23.                                                  LOCAL CONSTANTS
  24.  
  25. =============================================================================
  26. */
  27.  
  28. #ifndef SPEAR
  29.  
  30. #define BACKCOLOR       0x11
  31.  
  32.  
  33. #define WORDLIMIT       80
  34. #define FONTHEIGHT      10
  35. #define TOPMARGIN       16
  36. #define BOTTOMMARGIN    32
  37. #define LEFTMARGIN      16
  38. #define RIGHTMARGIN     16
  39. #define PICMARGIN       8
  40. #define TEXTROWS        ((200-TOPMARGIN-BOTTOMMARGIN)/FONTHEIGHT)
  41. #define SPACEWIDTH      7
  42. #define SCREENPIXWIDTH  320
  43. #define SCREENMID       (SCREENPIXWIDTH/2)
  44.  
  45. /*
  46. =============================================================================
  47.  
  48.                                 LOCAL VARIABLES
  49.  
  50. =============================================================================
  51. */
  52.  
  53. static int pagenum;
  54. static int numpages;
  55.  
  56. static unsigned leftmargin[TEXTROWS];
  57. static unsigned rightmargin[TEXTROWS];
  58. static char*    text;
  59. static unsigned rowon;
  60.  
  61. static int     picx;
  62. static int     picy;
  63. static int     picnum;
  64. static int     picdelay;
  65. static boolean layoutdone;
  66.  
  67. //===========================================================================
  68.  
  69. #ifndef JAPAN
  70. /*
  71. =====================
  72. =
  73. = RipToEOL
  74. =
  75. =====================
  76. */
  77.  
  78. void RipToEOL (void)
  79. {
  80.     while (*text++ != '\n')         // scan to end of line
  81.         ;
  82. }
  83.  
  84.  
  85. /*
  86. =====================
  87. =
  88. = ParseNumber
  89. =
  90. =====================
  91. */
  92.  
  93. int ParseNumber (void)
  94. {
  95.     char  ch;
  96.     char  num[80];
  97.     char *numptr;
  98.  
  99.     //
  100.     // scan until a number is found
  101.     //
  102.     ch = *text;
  103.     while (ch < '0' || ch >'9')
  104.         ch = *++text;
  105.  
  106.     //
  107.     // copy the number out
  108.     //
  109.     numptr = num;
  110.     do
  111.     {
  112.         *numptr++ = ch;
  113.         ch = *++text;
  114.     } while (ch >= '0' && ch <= '9');
  115.     *numptr = 0;
  116.  
  117.     return atoi (num);
  118. }
  119.  
  120.  
  121.  
  122. /*
  123. =====================
  124. =
  125. = ParsePicCommand
  126. =
  127. = Call with text pointing just after a ^P
  128. = Upon exit text points to the start of next line
  129. =
  130. =====================
  131. */
  132.  
  133. void ParsePicCommand (void)
  134. {
  135.     picy=ParseNumber();
  136.     picx=ParseNumber();
  137.     picnum=ParseNumber();
  138.     RipToEOL ();
  139. }
  140.  
  141.  
  142. void ParseTimedCommand (void)
  143. {
  144.     picy=ParseNumber();
  145.     picx=ParseNumber();
  146.     picnum=ParseNumber();
  147.     picdelay=ParseNumber();
  148.     RipToEOL ();
  149. }
  150.  
  151.  
  152. /*
  153. =====================
  154. =
  155. = TimedPicCommand
  156. =
  157. = Call with text pointing just after a ^P
  158. = Upon exit text points to the start of next line
  159. =
  160. =====================
  161. */
  162.  
  163. void TimedPicCommand (void)
  164. {
  165.     ParseTimedCommand ();
  166.  
  167.     //
  168.     // update the screen, and wait for time delay
  169.     //
  170.     VW_UpdateScreen ();
  171.  
  172.     //
  173.     // wait for time
  174.     //
  175.     Delay(picdelay);
  176.  
  177.     //
  178.     // draw pic
  179.     //
  180.     VWB_DrawPic (picx&~7,picy,picnum);
  181. }
  182.  
  183.  
  184. /*
  185. =====================
  186. =
  187. = HandleCommand
  188. =
  189. =====================
  190. */
  191.  
  192. void HandleCommand (void)
  193. {
  194.     int     i,margin,top,bottom;
  195.     int     picwidth,picheight,picmid;
  196.  
  197.     switch (toupper(*++text))
  198.     {
  199.         case 'B':
  200.             picy=ParseNumber();
  201.             picx=ParseNumber();
  202.             picwidth=ParseNumber();
  203.             picheight=ParseNumber();
  204.             VWB_Bar(picx,picy,picwidth,picheight,BACKCOLOR);
  205.             RipToEOL();
  206.             break;
  207.         case ';':               // comment
  208.             RipToEOL();
  209.             break;
  210.         case 'P':               // ^P is start of next page, ^E is end of file
  211.         case 'E':
  212.             layoutdone = true;
  213.             text--;             // back up to the '^'
  214.             break;
  215.  
  216.         case 'C':               // ^c<hex digit> changes text color
  217.             i = toupper(*++text);
  218.             if (i>='0' && i<='9')
  219.                 fontcolor = i-'0';
  220.             else if (i>='A' && i<='F')
  221.                 fontcolor = i-'A'+10;
  222.  
  223.             fontcolor *= 16;
  224.             i = toupper(*++text);
  225.             if (i>='0' && i<='9')
  226.                 fontcolor += i-'0';
  227.             else if (i>='A' && i<='F')
  228.                 fontcolor += i-'A'+10;
  229.             text++;
  230.             break;
  231.  
  232.         case '>':
  233.             px = 160;
  234.             text++;
  235.             break;
  236.  
  237.         case 'L':
  238.             py=ParseNumber();
  239.             rowon = (py-TOPMARGIN)/FONTHEIGHT;
  240.             py = TOPMARGIN+rowon*FONTHEIGHT;
  241.             px=ParseNumber();
  242.             while (*text++ != '\n')         // scan to end of line
  243.                 ;
  244.             break;
  245.  
  246.         case 'T':               // ^Tyyy,xxx,ppp,ttt waits ttt tics, then draws pic
  247.             TimedPicCommand ();
  248.             break;
  249.  
  250.         case 'G':               // ^Gyyy,xxx,ppp draws graphic
  251.             ParsePicCommand ();
  252.             VWB_DrawPic (picx&~7,picy,picnum);
  253.             picwidth = pictable[picnum-STARTPICS].width;
  254.             picheight = pictable[picnum-STARTPICS].height;
  255.             //
  256.             // adjust margins
  257.             //
  258.             picmid = picx + picwidth/2;
  259.             if (picmid > SCREENMID)
  260.                 margin = picx-PICMARGIN;                        // new right margin
  261.             else
  262.                 margin = picx+picwidth+PICMARGIN;       // new left margin
  263.  
  264.             top = (picy-TOPMARGIN)/FONTHEIGHT;
  265.             if (top<0)
  266.                 top = 0;
  267.             bottom = (picy+picheight-TOPMARGIN)/FONTHEIGHT;
  268.             if (bottom>=TEXTROWS)
  269.                 bottom = TEXTROWS-1;
  270.  
  271.             for (i=top;i<=bottom;i++)
  272.                 if (picmid > SCREENMID)
  273.                     rightmargin[i] = margin;
  274.                 else
  275.                     leftmargin[i] = margin;
  276.  
  277.             //
  278.             // adjust this line if needed
  279.             //
  280.             if (px < (int) leftmargin[rowon])
  281.                 px = leftmargin[rowon];
  282.             break;
  283.     }
  284. }
  285.  
  286.  
  287. /*
  288. =====================
  289. =
  290. = NewLine
  291. =
  292. =====================
  293. */
  294.  
  295. void NewLine (void)
  296. {
  297.     char    ch;
  298.  
  299.     if (++rowon == TEXTROWS)
  300.     {
  301.         //
  302.         // overflowed the page, so skip until next page break
  303.         //
  304.         layoutdone = true;
  305.         do
  306.         {
  307.             if (*text == '^')
  308.             {
  309.                 ch = toupper(*(text+1));
  310.                 if (ch == 'E' || ch == 'P')
  311.                 {
  312.                     layoutdone = true;
  313.                     return;
  314.                 }
  315.             }
  316.             text++;
  317.         } while (1);
  318.     }
  319.     px = leftmargin[rowon];
  320.     py+= FONTHEIGHT;
  321. }
  322.  
  323.  
  324.  
  325. /*
  326. =====================
  327. =
  328. = HandleCtrls
  329. =
  330. =====================
  331. */
  332.  
  333. void HandleCtrls (void)
  334. {
  335.     char    ch;
  336.  
  337.     ch = *text++;                   // get the character and advance
  338.  
  339.     if (ch == '\n')
  340.     {
  341.         NewLine ();
  342.         return;
  343.     }
  344. }
  345.  
  346.  
  347. /*
  348. =====================
  349. =
  350. = HandleWord
  351. =
  352. =====================
  353. */
  354.  
  355. void HandleWord (void)
  356. {
  357.     char    wword[WORDLIMIT];
  358.     int     wordindex;
  359.     word    wwidth,wheight,newpos;
  360.  
  361.  
  362.     //
  363.     // copy the next word into [word]
  364.     //
  365.     wword[0] = *text++;
  366.     wordindex = 1;
  367.     while (*text>32)
  368.     {
  369.         wword[wordindex] = *text++;
  370.         if (++wordindex == WORDLIMIT)
  371.             Quit ("PageLayout: Word limit exceeded");
  372.     }
  373.     wword[wordindex] = 0;            // stick a null at end for C
  374.  
  375.     //
  376.     // see if it fits on this line
  377.     //
  378.     VW_MeasurePropString (wword,&wwidth,&wheight);
  379.  
  380.     while (px+wwidth > (int) rightmargin[rowon])
  381.     {
  382.         NewLine ();
  383.         if (layoutdone)
  384.             return;         // overflowed page
  385.     }
  386.  
  387.     //
  388.     // print it
  389.     //
  390.     newpos = px+wwidth;
  391.     VWB_DrawPropString (wword);
  392.     px = newpos;
  393.  
  394.     //
  395.     // suck up any extra spaces
  396.     //
  397.     while (*text == ' ')
  398.     {
  399.         px += SPACEWIDTH;
  400.         text++;
  401.     }
  402. }
  403.  
  404. /*
  405. =====================
  406. =
  407. = PageLayout
  408. =
  409. = Clears the screen, draws the pics on the page, and word wraps the text.
  410. = Returns a pointer to the terminating command
  411. =
  412. =====================
  413. */
  414.  
  415. void PageLayout (boolean shownumber)
  416. {
  417.     int     i,oldfontcolor;
  418.     char    ch;
  419.  
  420.     oldfontcolor = fontcolor;
  421.  
  422.     fontcolor = 0;
  423.  
  424.     //
  425.     // clear the screen
  426.     //
  427.     VWB_Bar (0,0,320,200,BACKCOLOR);
  428.     VWB_DrawPic (0,0,H_TOPWINDOWPIC);
  429.     VWB_DrawPic (0,8,H_LEFTWINDOWPIC);
  430.     VWB_DrawPic (312,8,H_RIGHTWINDOWPIC);
  431.     VWB_DrawPic (8,176,H_BOTTOMINFOPIC);
  432.  
  433.  
  434.     for (i=0; i<TEXTROWS; i++)
  435.     {
  436.         leftmargin[i] = LEFTMARGIN;
  437.         rightmargin[i] = SCREENPIXWIDTH-RIGHTMARGIN;
  438.     }
  439.  
  440.     px = LEFTMARGIN;
  441.     py = TOPMARGIN;
  442.     rowon = 0;
  443.     layoutdone = false;
  444.  
  445.     //
  446.     // make sure we are starting layout text (^P first command)
  447.     //
  448.     while (*text <= 32)
  449.         text++;
  450.  
  451.     if (*text != '^' || toupper(*++text) != 'P')
  452.         Quit ("PageLayout: Text not headed with ^P");
  453.  
  454.     while (*text++ != '\n')
  455.         ;
  456.  
  457.  
  458.     //
  459.     // process text stream
  460.     //
  461.     do
  462.     {
  463.         ch = *text;
  464.  
  465.         if (ch == '^')
  466.             HandleCommand ();
  467.         else
  468.             if (ch == 9)
  469.             {
  470.                 px = (px+8)&0xf8;
  471.                 text++;
  472.             }
  473.             else if (ch <= 32)
  474.                 HandleCtrls ();
  475.             else
  476.                 HandleWord ();
  477.  
  478.     } while (!layoutdone);
  479.  
  480.     pagenum++;
  481.  
  482.     if (shownumber)
  483.     {
  484. #ifdef SPANISH
  485.         sprintf(str, "Hoja %d de %d", pagenum, numpages);
  486.         px = 208;
  487. #else
  488.         sprintf(str, "pg %d of %d", pagenum, numpages);
  489.         px = 213;
  490. #endif
  491.         py = 183;
  492.         fontcolor = 0x4f;                          //12^BACKCOLOR;
  493.  
  494.         VWB_DrawPropString (str);
  495.     }
  496.  
  497.     fontcolor = oldfontcolor;
  498. }
  499.  
  500. //===========================================================================
  501.  
  502. /*
  503. =====================
  504. =
  505. = BackPage
  506. =
  507. = Scans for a previous ^P
  508. =
  509. =====================
  510. */
  511.  
  512. void BackPage (void)
  513. {
  514.     pagenum--;
  515.     do
  516.     {
  517.         text--;
  518.         if (*text == '^' && toupper(*(text+1)) == 'P')
  519.             return;
  520.     } while (1);
  521. }
  522.  
  523.  
  524. //===========================================================================
  525.  
  526.  
  527. /*
  528. =====================
  529. =
  530. = CacheLayoutGraphics
  531. =
  532. = Scans an entire layout file (until a ^E) marking all graphics used, and
  533. = counting pages, then caches the graphics in
  534. =
  535. =====================
  536. */
  537. void CacheLayoutGraphics (void)
  538. {
  539.     char    *bombpoint, *textstart;
  540.     char    ch;
  541.  
  542.     textstart = text;
  543.     bombpoint = text+30000;
  544.     numpages = pagenum = 0;
  545.  
  546.     do
  547.     {
  548.         if (*text == '^')
  549.         {
  550.             ch = toupper(*++text);
  551.             if (ch == 'P')          // start of a page
  552.                 numpages++;
  553.             if (ch == 'E')          // end of file, so load graphics and return
  554.             {
  555. #ifndef SPEAR
  556.                 CA_CacheGrChunk(H_TOPWINDOWPIC);
  557.                 CA_CacheGrChunk(H_LEFTWINDOWPIC);
  558.                 CA_CacheGrChunk(H_RIGHTWINDOWPIC);
  559.                 CA_CacheGrChunk(H_BOTTOMINFOPIC);
  560. #endif
  561.                 //                              CA_CacheMarks ();
  562.                 text = textstart;
  563.                 return;
  564.             }
  565.             if (ch == 'G')          // draw graphic command, so mark graphics
  566.             {
  567.                 ParsePicCommand ();
  568.                 CA_CacheGrChunk (picnum);
  569.             }
  570.             if (ch == 'T')          // timed draw graphic command, so mark graphics
  571.             {
  572.                 ParseTimedCommand ();
  573.                 CA_CacheGrChunk (picnum);
  574.             }
  575.         }
  576.         else
  577.             text++;
  578.  
  579.     } while (text<bombpoint);
  580.  
  581.     Quit ("CacheLayoutGraphics: No ^E to terminate file!");
  582. }
  583. #endif
  584.  
  585.  
  586. /*
  587. =====================
  588. =
  589. = ShowArticle
  590. =
  591. =====================
  592. */
  593.  
  594. #ifdef JAPAN
  595. void ShowArticle (int which)
  596. #else
  597. void ShowArticle (char *article)
  598. #endif
  599. {
  600. #ifdef JAPAN
  601.     int snames[10] = {
  602.         H_HELP1PIC,
  603.         H_HELP2PIC,
  604.         H_HELP3PIC,
  605.         H_HELP4PIC,
  606.         H_HELP5PIC,
  607.         H_HELP6PIC,
  608.         H_HELP7PIC,
  609.         H_HELP8PIC,
  610.         H_HELP9PIC,
  611.         H_HELP10PIC};
  612.     int enames[14] = {
  613.         0,0,
  614. #ifndef JAPDEMO
  615.         C_ENDGAME1APIC,
  616.         C_ENDGAME1BPIC,
  617.         C_ENDGAME2APIC,
  618.         C_ENDGAME2BPIC,
  619.         C_ENDGAME3APIC,
  620.         C_ENDGAME3BPIC,
  621.         C_ENDGAME4APIC,
  622.         C_ENDGAME4BPIC,
  623.         C_ENDGAME5APIC,
  624.         C_ENDGAME5BPIC,
  625.         C_ENDGAME6APIC,
  626.         C_ENDGAME6BPIC
  627. #endif
  628.     };
  629. #endif
  630.     unsigned    oldfontnumber;
  631.     boolean     newpage,firstpage;
  632.     ControlInfo ci;
  633.  
  634. #ifdef JAPAN
  635.     pagenum = 1;
  636.     if (!which)
  637.         numpages = 10;
  638.     else
  639.         numpages = 2;
  640. #else
  641.     text = article;
  642.     oldfontnumber = fontnumber;
  643.     fontnumber = 0;
  644.     CA_CacheGrChunk(STARTFONT);
  645.     VWB_Bar (0,0,320,200,BACKCOLOR);
  646.     CacheLayoutGraphics ();
  647. #endif
  648.  
  649.     newpage = true;
  650.     firstpage = true;
  651.  
  652.     do
  653.     {
  654.         if (newpage)
  655.         {
  656.             newpage = false;
  657. #ifdef JAPAN
  658.             if (!which)
  659.                 CA_CacheScreen(snames[pagenum - 1]);
  660.             else
  661.                 CA_CacheScreen(enames[which*2 + pagenum - 1]);
  662. #else
  663.             PageLayout (true);
  664. #endif
  665.             VW_UpdateScreen ();
  666.             if (firstpage)
  667.             {
  668.                 VL_FadeIn(0,255,gamepal,10);
  669.                 firstpage = false;
  670.             }
  671.         }
  672.         SDL_Delay(5);
  673.  
  674.         LastScan = 0;
  675.         ReadAnyControl(&ci);
  676.         Direction dir = ci.dir;
  677.         switch(dir)
  678.         {
  679.             case dir_North:
  680.             case dir_South:
  681.                 break;
  682.  
  683.             default:
  684.                 if(ci.button0) dir = dir_South;
  685.                 switch(LastScan)
  686.                 {
  687.                     case sc_UpArrow:
  688.                     case sc_PgUp:
  689.                     case sc_LeftArrow:
  690.                         dir = dir_North;
  691.                         break;
  692.  
  693.                     case sc_Enter:
  694.                     case sc_DownArrow:
  695.                     case sc_PgDn:
  696.                     case sc_RightArrow:
  697.                         dir = dir_South;
  698.                         break;
  699.                 }
  700.                 break;
  701.         }
  702.  
  703.         switch(dir)
  704.         {
  705.             case dir_North:
  706.             case dir_West:
  707.                 if (pagenum>1)
  708.                 {
  709. #ifndef JAPAN
  710.                     BackPage ();
  711.                     BackPage ();
  712. #else
  713.                   pagenum--;
  714. #endif
  715.                     newpage = true;
  716.                 }
  717.                 TicDelay(20);
  718.                 break;
  719.  
  720.             case dir_South:
  721.             case dir_East:
  722.                 if (pagenum<numpages)
  723.                 {
  724.                     newpage = true;
  725. #ifdef JAPAN
  726.                     pagenum++;
  727. #endif
  728.                 }
  729.                 TicDelay(20);
  730.                 break;
  731.         }
  732.     } while (LastScan != sc_Escape && !ci.button1);
  733.  
  734.     IN_ClearKeysDown ();
  735.     fontnumber = oldfontnumber;
  736. }
  737.  
  738.  
  739. //===========================================================================
  740.  
  741. #ifndef JAPAN
  742. #ifdef ARTSEXTERN
  743. int     endextern = T_ENDART1;
  744. #ifndef SPEAR
  745. int     helpextern = T_HELPART;
  746. #endif
  747. #endif
  748. char helpfilename[13] = "HELPART.",
  749.     endfilename[13] = "ENDART1.";
  750. #endif
  751.  
  752. /*
  753. =================
  754. =
  755. = HelpScreens
  756. =
  757. =================
  758. */
  759. #ifndef SPEAR
  760. void HelpScreens (void)
  761. {
  762.     int     artnum;
  763.     char    *text;
  764. #ifndef ARTSEXTERN
  765.     memptr  layout;
  766. #endif
  767.  
  768.  
  769. #ifdef JAPAN
  770.     ShowArticle (0);
  771.     VW_FadeOut();
  772.     FreeMusic ();
  773. #else
  774.  
  775. #ifdef ARTSEXTERN
  776.     artnum = helpextern;
  777.     CA_CacheGrChunk (artnum);
  778.     text = (char *)grsegs[artnum];
  779. #else
  780.     CA_LoadFile (helpfilename,&layout);
  781.     text = (char *)layout;
  782. #endif
  783.  
  784.     ShowArticle (text);
  785.  
  786. #ifdef ARTSEXTERN
  787.     UNCACHEGRCHUNK(artnum);
  788. #else
  789.     free(layout);
  790. #endif
  791.  
  792.     VW_FadeOut();
  793.  
  794.     FreeMusic ();
  795. #endif
  796. }
  797. #endif
  798.  
  799. //
  800. // END ARTICLES
  801. //
  802. void EndText (void)
  803. {
  804.     int     artnum;
  805.     char    *text;
  806. #ifndef ARTSEXTERN
  807.     memptr  layout;
  808. #endif
  809.  
  810.     ClearMemory ();
  811.  
  812. #ifdef JAPAN
  813.     ShowArticle(gamestate.episode + 1);
  814.  
  815.     VW_FadeOut();
  816.  
  817.     SETFONTCOLOR(0,15);
  818.     IN_ClearKeysDown();
  819.     if (MousePresent && IN_IsInputGrabbed())
  820.         IN_CenterMouse();  // Clear accumulated mouse movement
  821.  
  822.     FreeMusic ();
  823. #else
  824.  
  825.  
  826.  
  827. #ifdef ARTSEXTERN
  828.     artnum = endextern+gamestate.episode;
  829.     CA_CacheGrChunk (artnum);
  830.     text = (char *)grsegs[artnum];
  831. #else
  832.     endfilename[6] = '1'+gamestate.episode;
  833.     CA_LoadFile (endfilename,&layout);
  834.     text = (char *)layout;
  835. #endif
  836.  
  837.     ShowArticle (text);
  838.  
  839. #ifdef ARTSEXTERN
  840.     UNCACHEGRCHUNK(artnum);
  841. #else
  842.     free(layout);
  843. #endif
  844.  
  845.  
  846.     VW_FadeOut();
  847.     SETFONTCOLOR(0,15);
  848.     IN_ClearKeysDown();
  849.     if (MousePresent && IN_IsInputGrabbed())
  850.         IN_CenterMouse();  // Clear accumulated mouse movement
  851.  
  852.     FreeMusic ();
  853. #endif
  854. }
  855. #endif
  856.