summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/wl_text.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/wl_text.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/wl_text.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/wl_text.c859
1 files changed, 859 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/wl_text.c b/apps/plugins/sdl/progs/wolf3d/wl_text.c
new file mode 100644
index 0000000000..d51117b836
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/wl_text.c
@@ -0,0 +1,859 @@
1// WL_TEXT.C
2
3#include "wl_def.h"
4#pragma hdrstop
5
6/*
7=============================================================================
8
9TEXT 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
53static int pagenum;
54static int numpages;
55
56static unsigned leftmargin[TEXTROWS];
57static unsigned rightmargin[TEXTROWS];
58static char* text;
59static unsigned rowon;
60
61static int picx;
62static int picy;
63static int picnum;
64static int picdelay;
65static boolean layoutdone;
66
67//===========================================================================
68
69#ifndef JAPAN
70/*
71=====================
72=
73= RipToEOL
74=
75=====================
76*/
77
78void 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
93int 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
133void ParsePicCommand (void)
134{
135 picy=ParseNumber();
136 picx=ParseNumber();
137 picnum=ParseNumber();
138 RipToEOL ();
139}
140
141
142void 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
163void 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
192void 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
295void 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
333void 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
355void 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
415void 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
512void 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*/
537void 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
595void ShowArticle (int which)
596#else
597void 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
743int endextern = T_ENDART1;
744#ifndef SPEAR
745int helpextern = T_HELPART;
746#endif
747#endif
748char helpfilename[13] = "HELPART.",
749 endfilename[13] = "ENDART1.";
750#endif
751
752/*
753=================
754=
755= HelpScreens
756=
757=================
758*/
759#ifndef SPEAR
760void HelpScreens (void)
761{
762 int artnum;
763 char *text;
764#ifndef ARTSEXTERN
765 memptr layout;
766#endif
767
768
769 // CA_UpLevel ();
770 // MM_SortMem ();
771#ifdef JAPAN
772 ShowArticle (0);
773 VW_FadeOut();
774 FreeMusic ();
775 CA_DownLevel ();
776 MM_SortMem ();
777#else
778
779#ifdef ARTSEXTERN
780 artnum = helpextern;
781 CA_CacheGrChunk (artnum);
782 text = (char *)grsegs[artnum];
783#else
784 CA_LoadFile (helpfilename,&layout);
785 text = (char *)layout;
786#endif
787
788 ShowArticle (text);
789
790#ifdef ARTSEXTERN
791 UNCACHEGRCHUNK(artnum);
792#else
793 free(layout);
794#endif
795
796 VW_FadeOut();
797
798 FreeMusic ();
799#endif
800}
801#endif
802
803//
804// END ARTICLES
805//
806void EndText (void)
807{
808 int artnum;
809 char *text;
810#ifndef ARTSEXTERN
811 memptr layout;
812#endif
813
814 ClearMemory ();
815
816#ifdef JAPAN
817 ShowArticle(gamestate.episode + 1);
818
819 VW_FadeOut();
820
821 SETFONTCOLOR(0,15);
822 IN_ClearKeysDown();
823 if (MousePresent && IN_IsInputGrabbed())
824 IN_CenterMouse(); // Clear accumulated mouse movement
825
826 FreeMusic ();
827#else
828
829
830
831#ifdef ARTSEXTERN
832 artnum = endextern+gamestate.episode;
833 CA_CacheGrChunk (artnum);
834 text = (char *)grsegs[artnum];
835#else
836 endfilename[6] = '1'+gamestate.episode;
837 CA_LoadFile (endfilename,&layout);
838 text = (char *)layout;
839#endif
840
841 ShowArticle (text);
842
843#ifdef ARTSEXTERN
844 UNCACHEGRCHUNK(artnum);
845#else
846 free(layout);
847#endif
848
849
850 VW_FadeOut();
851 SETFONTCOLOR(0,15);
852 IN_ClearKeysDown();
853 if (MousePresent && IN_IsInputGrabbed())
854 IN_CenterMouse(); // Clear accumulated mouse movement
855
856 FreeMusic ();
857#endif
858}
859#endif