wolf3d

The original open source release of Wolfenstein 3D
Log | Files | Refs

WL_TEXT.C (13613B)


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