1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 // RT_BUILD.C
21
22 #include "rt_def.h"
23 #include <string.h>
24 #include "watcom.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #ifdef DOS
29 #include <dos.h>
30 #include <conio.h>
31 #endif
32
33 #include "rt_build.h"
34 #include "_rt_buil.h"
35 #include "rt_dr_a.h"
36 #include "rt_draw.h"
37 #include "rt_scale.h"
38 #include "rt_menu.h"
39 #include "rt_main.h"
40 #include "isr.h"
41 #include "rt_util.h"
42 #include "engine.h"
43 #include "lumpy.h"
44 #include "rt_fc_a.h"
45 #include "z_zone.h"
46 #include "w_wad.h"
47 #include "rt_view.h"
48 #include "rt_cfg.h"
49 #include "rt_vid.h"
50
51 #include "rt_sound.h"
52 #include "modexlib.h"
53 #include "rt_str.h"
54 //MED
55 #include "memcheck.h"
56
57 byte * intensitytable;
58
59
60 // LOCAL VARIABLES
61
62 static byte * menubuf;
63 static byte * menubuffers[2];
64 static char menutitles[2][40];
65 static int alternatemenubuf=0;
66 static int titleshade=16;
67 static int titleshadedir=1;
68 static int titleyoffset=0;
69 static char titlestring[40]="\0";
70 static int readytoflip;
71 static boolean MenuBufStarted=false;
72 static int mindist=0x2700;
73 static boolean BackgroundDrawn=false;
74
75 static plane_t planelist[MAXPLANES],*planeptr;
76
77 static int StringShade=16;
78
79 extern void (*USL_MeasureString)(const char *, int *, int *, font_t *);
80
81 static char strbuf[MaxString];
82
83 //******************************************************************************
84 //
85 // DrawRotPost
86 //
87 //******************************************************************************
88
DrawRotPost(int height,byte * src,byte * buf,int origheight)89 void DrawRotPost ( int height, byte * src, byte * buf, int origheight)
90 {
91 int y1;
92 int y2;
93
94 hp_srcstep=(origheight<<18)/height;
95 y1 = (((centery<<8)-(height<<5)+(MENUOFFY<<8)));
96 y2 = (((height<<6)+y1)>>8);
97
98 if (((y1>>8)>=200) || (y2<0))
99 return;
100 if (y1<0)
101 {
102 hp_startfrac=FixedMulShift(-y1,hp_srcstep,8);
103 y2 = (((height<<6)+y1)>>8);
104 y1=0;
105 }
106 else
107 {
108 hp_startfrac=FixedMulShift(255-(y1&0xff),hp_srcstep,8);
109 y1>>=8;
110 }
111 if (y2>200)
112 {
113 DrawMenuPost(200-y1, src, buf+ylookup[y1]);
114 }
115 else
116 {
117 DrawMenuPost(y2-y1, src, buf+ylookup[y1]);
118 }
119 }
120
121
122
123 /*
124 ========================
125 =
126 = GetPoint
127 =
128 ========================
129 */
130
GetPoint(int x1,int y1,int px,int py,int * screenx,int * height,int angle)131 void GetPoint (int x1, int y1, int px, int py, int * screenx, int * height, int angle)
132 {
133
134 fixed gxt,gyt,nx,ny;
135 fixed gxtt,gytt;
136 int gx,gy;
137
138
139 //
140 // translate point to view centered coordinates
141 //
142 gx = x1-px;
143 gy = y1-py;
144
145 //
146 // calculate newx
147 //
148 gxt = FixedMul(gx,costable[angle]);
149 gyt = FixedMul(gy,sintable[angle]);
150 nx =gxt-gyt;
151
152 if (nx<mindist)
153 nx=mindist;
154
155
156 //
157 // calculate newy
158 //
159 gxtt = FixedMul(gx,sintable[angle]);
160 gytt = FixedMul(gy,costable[angle]);
161 ny = gytt+gxtt;
162
163 // too close, don't overflow the divid'
164
165
166 *screenx = 160 + ((ny*NORMALWIDTHMULTIPLIER)/nx); // DEBUG: use assembly divide
167
168 *height = NORMALHEIGHTDIVISOR/nx;
169
170 if (*screenx<0) *screenx=0;
171
172 }
173
174
175 /*
176 ========================
177 =
178 = InterpolatePlane
179 =
180 ========================
181 */
182
InterpolatePlane(visobj_t * plane)183 void InterpolatePlane (visobj_t * plane)
184 {
185 int d1,d2;
186 int top;
187 int topinc;
188 int bot;
189 int botinc;
190 int i;
191 int texture;
192 int dh;
193 int dx;
194 int height;
195
196
197 dx=(plane->x2-plane->x1+1);
198 if (plane->h1<=0 || plane->h2<=0 || (dx==0))
199 return;
200 d1=65536/plane->h1;
201 d2=65536/plane->h2;
202 dh=((plane->h2-plane->h1)<<8)/dx;
203 top=0;
204 topinc=(d1)*((plane->textureend-plane->texturestart)>>4);
205 bot=d2*dx;
206 botinc=d1-d2;
207 height=(plane->h1<<8);
208 if (plane->x1>=viewwidth)
209 return;
210 for (i=plane->x1;i<=plane->x2;i++)
211 {
212 if ((i>=0 && i<viewwidth)&&(posts[i].wallheight<(height>>8)))
213 {
214 if (bot)
215 {
216 texture=((top/bot)+(plane->texturestart>>4))>>6;
217 posts[i].texture=texture*plane->viewx;
218 posts[i].lump=plane->shapenum;
219 posts[i].wallheight=(height>>8);
220 posts[i].offset=plane->viewx;
221 }
222 }
223 top+=topinc;
224 bot+=botinc;
225 height+=dh;
226 }
227 }
228
229 //******************************************************************************
230 //
231 // DrawPlanePosts
232 //
233 //******************************************************************************
234
DrawPlanePosts(void)235 void DrawPlanePosts (void)
236 {
237 int height;
238 char * buf;
239 byte * shape;
240 int lastwall=-2;
241 int plane;
242 int i;
243
244 shadingtable=colormap+(16<<8);
245
246 #ifdef DOS
247 for (plane=0;plane<4;plane++)
248 #endif
249
250 {
251 VGAWRITEMAP(plane);
252 buf=(byte *)(bufferofs);
253
254 #ifdef DOS
255 for (i=plane;i<viewwidth;i+=4,buf++)
256 #else
257 for (i=0;i<viewwidth;i++,buf++)
258 #endif
259 {
260 height=(posts[i].wallheight);
261 if (height<=4)
262 continue;
263 if (lastwall!=posts[i].lump)
264 {
265 lastwall=posts[i].lump;
266 if (lastwall==-1)
267 shape=menubuf;
268 else
269 shape=W_CacheLumpNum(lastwall,PU_CACHE, Cvt_patch_t, 1);
270 }
271 DrawRotPost (height,shape+posts[i].texture,buf,posts[i].offset);
272 }
273 }
274 }
275
276 //******************************************************************************
277 //
278 // NextPlaneptr
279 //
280 //******************************************************************************
281
NextPlaneptr(void)282 void NextPlaneptr ( void )
283 {
284 if (planeptr < &planelist[MAXPLANES-1]) // don't let it overflo'
285 planeptr++;
286 }
287
288 //******************************************************************************
289 //
290 // RestPlaneptr
291 //
292 //******************************************************************************
293
ResetPlaneptr(void)294 void ResetPlaneptr ( void )
295 {
296 planeptr = &planelist[0];
297 }
298
299 //******************************************************************************
300 //
301 // NextVisptr
302 //
303 //******************************************************************************
304
NextVisptr(void)305 void NextVisptr ( void )
306 {
307 if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
308 visptr++;
309 }
310
311 //******************************************************************************
312 //
313 // ResetVisptr
314 //
315 //******************************************************************************
316
ResetVisptr(void)317 void ResetVisptr ( void )
318 {
319 visptr = &vislist[0];
320 }
321
322 //******************************************************************************
323 //
324 // SetupPlanes
325 //
326 //******************************************************************************
327
SetupPlanes(void)328 void SetupPlanes ( void )
329 {
330 int i;
331
332 for (i=0;i<320;i++)
333 posts[i].wallheight=-1;
334 }
335
336
337
338 //******************************************************************************
339 //
340 // CalcPlanes
341 //
342 //******************************************************************************
343
CalcPlanes(int px,int py,int angle)344 void CalcPlanes ( int px, int py, int angle )
345 {
346 plane_t * pptr;
347
348 ResetVisptr();
349 for (pptr = &planelist[0]; pptr<planeptr; pptr++)
350 {
351 if (SideOfLine(pptr->x1,pptr->y1,pptr->x2,pptr->y2,px,py)<0)
352 {
353 GetPoint (pptr->x1,pptr->y1,px,py,&visptr->x1,&visptr->h1,angle);
354 GetPoint (pptr->x2,pptr->y2,px,py,&visptr->x2,&visptr->h2,angle);
355 visptr->textureend=0x0;
356 visptr->texturestart=pptr->texturewidth;
357 }
358 else
359 {
360 GetPoint (pptr->x2,pptr->y2,px,py,&visptr->x1,&visptr->h1,angle);
361 GetPoint (pptr->x1,pptr->y1,px,py,&visptr->x2,&visptr->h2,angle);
362 visptr->texturestart=0x0;
363 visptr->textureend=pptr->texturewidth;
364 }
365 visptr->shapenum=pptr->texture;
366 visptr->viewx=pptr->origheight;
367 visptr->viewheight=MAX(visptr->h1,visptr->h2);
368 NextVisptr();
369 }
370 }
371
372
373 //******************************************************************************
374 //
375 // DrawTransformedPlanes
376 //
377 //******************************************************************************
378
DrawTransformedPlanes(void)379 void DrawTransformedPlanes ( void )
380 {
381 int numvisible;
382 int greatest;
383 int height;
384 int i;
385 visobj_t * closest;
386
387 numvisible = visptr-&vislist[0];
388 if (!numvisible)
389 return; // no visible objects
390 for (i = 0; i<numvisible; i++)
391 {
392 greatest = 0;
393 for (visstep=&vislist[0] ; visstep<visptr ; visstep++)
394 {
395 height = visstep->viewheight;
396 if (height > greatest)
397 {
398 greatest = height;
399 closest = visstep;
400 }
401 }
402 InterpolatePlane(closest);
403 closest->viewheight = 0;
404 }
405 }
406
407
408 //******************************************************************************
409 //
410 // ClearMenuBuf
411 //
412 //******************************************************************************
413
ClearMenuBuf(void)414 void ClearMenuBuf ( void )
415 {
416 byte * shape;
417
418 if (MenuBufStarted==false)
419 Error("Called ClearMenuBuf without menubuf started\n");
420
421 shape=W_CacheLumpName(MENUBACKNAME,PU_CACHE, Cvt_patch_t, 1);
422 shape+=8;
423 memcpy (menubuf,shape,TEXTUREW*TEXTUREHEIGHT);
424 }
425
426 //******************************************************************************
427 //
428 // ShutdownMenuBuf
429 //
430 //******************************************************************************
431
ShutdownMenuBuf(void)432 void ShutdownMenuBuf ( void )
433 {
434 if (MenuBufStarted==false)
435 return;
436 MenuBufStarted=false;
437 SafeFree(menubuffers[0]);
438 SafeFree(menubuffers[1]);
439 if (loadedgame==false)
440 SetViewSize(viewsize);
441 }
442
443 //******************************************************************************
444 //
445 // SetupMenuBuf
446 //
447 //******************************************************************************
448
SetupMenuBuf(void)449 void SetupMenuBuf ( void )
450 {
451 #define SRCH 148
452 #define SRCW 258
453 #define PLANEX1 (-0x24000)
454 #define PLANEX2 (0x23fff)
455 #define PLANEW (16<<10)
456 #define PLANEY (0x40000)
457 #define PLANEW2 (0x5a827)
458
459 if (MenuBufStarted==true)
460 return;
461 MenuBufStarted=true;
462
463 // No top offsets like in game
464
465 centery=100;
466 centeryfrac=centery<<16;
467
468 strcpy(titlestring,menutitles[0]);
469
470 screenofs=0;
471 viewwidth=320;
472 viewheight=200;
473
474 alternatemenubuf=0;
475
476 ResetPlaneptr();
477 planeptr->texture=-1;
478 planeptr->y1=PLANEX1;
479 planeptr->x1=PLANEW;
480 planeptr->y2=PLANEX2;
481 planeptr->x2=PLANEW;
482 planeptr->origheight=TEXTUREHEIGHT;
483 planeptr->texturewidth=TEXTUREWIDTH;
484 NextPlaneptr();
485 planeptr->texture=-1;
486 planeptr->y1=PLANEX1;
487 planeptr->x1=-PLANEW;
488 planeptr->y2=PLANEX2;
489 planeptr->x2=-PLANEW;
490 planeptr->origheight=TEXTUREHEIGHT;
491 planeptr->texturewidth=TEXTUREWIDTH;
492 NextPlaneptr();
493 planeptr->texture=W_GetNumForName(MENUBACKNAME);
494 planeptr->y1=PLANEX1;
495 planeptr->x1=PLANEW;
496 planeptr->y2=PLANEX1;
497 planeptr->x2=-PLANEW;
498 planeptr->origheight=TEXTUREHEIGHT;
499 planeptr->texturewidth=TEXTUREWIDTH;
500 NextPlaneptr();
501 planeptr->texture=W_GetNumForName(MENUBACKNAME);
502 planeptr->y1=PLANEX2;
503 planeptr->x1=PLANEW;
504 planeptr->y2=PLANEX2;
505 planeptr->x2=-PLANEW;
506 planeptr->origheight=TEXTUREHEIGHT;
507 planeptr->texturewidth=TEXTUREWIDTH;
508 NextPlaneptr();
509
510 menubuffers[0]=SafeMalloc(TEXTUREW*TEXTUREHEIGHT);
511 menubuffers[1]=SafeMalloc(TEXTUREW*TEXTUREHEIGHT);
512 menubuf=menubuffers[0];
513 ClearMenuBuf();
514 BackgroundDrawn=false;
515 }
516
517
518 //******************************************************************************
519 //
520 // PositionMenuBuf
521 //
522 //******************************************************************************
523
PositionMenuBuf(int angle,int distance,boolean drawbackground)524 void PositionMenuBuf( int angle, int distance, boolean drawbackground )
525 {
526 int px,py;
527 font_t * oldfont;
528 int width,height;
529
530
531 if (MenuBufStarted==false)
532 Error("Called PositionMenuBuf without menubuf started\n");
533 CalcTics();
534 SetupPlanes();
535 if ((drawbackground==true) || (BackgroundDrawn==false))
536 {
537 VL_DrawPostPic (W_GetNumForName("trilogo"));
538 }
539 px=FixedMulShift(distance,costable[angle&(FINEANGLES-1)],16);
540 py=FixedMulShift(-distance,sintable[angle&(FINEANGLES-1)],16);
541 CalcPlanes(px,py,(angle+ANG180)&(FINEANGLES-1));
542 DrawTransformedPlanes();
543 DrawPlanePosts();
544 oldfont=CurrentFont;
545 CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
546 US_MeasureStr (&width, &height, titlestring);
547 US_ClippedPrint ((320-width)>>1, MENUTITLEY-titleyoffset, titlestring);
548 CurrentFont=oldfont;
549 FlipPage();
550 titleshade+=titleshadedir;
551 if (abs(titleshade-16)>6)
552 titleshadedir=-titleshadedir;
553 if (BackgroundDrawn==false)
554 {
555 VL_CopyDisplayToHidden();
556 BackgroundDrawn=true;
557 }
558 }
559
560 //******************************************************************************
561 //
562 // RefreshMenuBuf
563 //
564 //******************************************************************************
565
RefreshMenuBuf(int time)566 void RefreshMenuBuf( int time )
567 {
568 int i;
569
570 if (MenuBufStarted==false)
571 Error("Called RefreshMenuBuf without menubuf started\n");
572
573 if (readytoflip)
574 return;
575
576 for (i=0;i<=time;i+=tics)
577 {
578 PositionMenuBuf (0,NORMALVIEW,false);
579 }
580 }
581
582 //******************************************************************************
583 //
584 // ScaleMenuBufPost
585 //
586 //******************************************************************************
587
ScaleMenuBufPost(byte * src,int topoffset,byte * buf)588 void ScaleMenuBufPost (byte * src, int topoffset, byte * buf)
589 {
590 int d;
591 int offset;
592 int length;
593 int s;
594
595
596 while (1)
597 {
598 offset=*(src++);
599 if (offset==0xff)
600 return;
601 else
602 {
603 d=offset-topoffset;
604 length=*(src++);
605 for (s=0;s<length;s++,d++)
606 *(buf+d)=*(src+s);
607 src+=length;
608 }
609 }
610 }
611
612 //******************************************************************************
613 //
614 // SetAlternateMenuBuf
615 //
616 //******************************************************************************
617
SetAlternateMenuBuf(void)618 void SetAlternateMenuBuf ( void )
619 {
620 if (MenuBufStarted==false)
621 Error("Called SetAlternateMenuBuf without menubuf started\n");
622
623 alternatemenubuf^=1;
624 readytoflip=1;
625 menubuf=menubuffers[alternatemenubuf];
626 }
627
628 //******************************************************************************
629 //
630 // SetMenuTitle
631 //
632 //******************************************************************************
633
SetMenuTitle(const char * menutitle)634 void SetMenuTitle ( const char * menutitle )
635 {
636 if (MenuBufStarted==false)
637 Error("Called SetMenuTitle without menubuf started\n");
638 strcpy(menutitles[alternatemenubuf],menutitle);
639 if (readytoflip==0)
640 strcpy(titlestring,menutitle);
641 }
642
643 //******************************************************************************
644 //
645 // DrawMenuBufPicture
646 //
647 //******************************************************************************
648
DrawMenuBufPicture(int x,int y,const byte * pic,int w,int h)649 void DrawMenuBufPicture (int x, int y, const byte * pic, int w, int h)
650 {
651 byte *buffer;
652 int i;
653
654 if (MenuBufStarted==false)
655 Error("Called DrawMenuBufPictoure without menubuf started\n");
656
657 if ((x<0) || (x+w>=TEXTUREW))
658 Error ("DrawMenuBufPicture: x is out of range\n");
659 if ((y<0) || (y+h>=TEXTUREHEIGHT))
660 Error ("DrawMenuBufPicture: y is out of range\n");
661
662 for (i=0;i<w;i++)
663 {
664 buffer = (byte*)menubuf+y+((x+i)*TEXTUREHEIGHT);
665 memcpy(buffer,pic,h);
666 pic+=h;
667 }
668 }
669
670 //******************************************************************************
671 //
672 // DrawMenuBufItem
673 //
674 //******************************************************************************
675
DrawMenuBufItem(int x,int y,int shapenum)676 void DrawMenuBufItem (int x, int y, int shapenum)
677 {
678 byte *buffer;
679 int cnt;
680 byte *shape;
681 patch_t *p;
682
683 if (MenuBufStarted==false)
684 Error("Called DrawMenuBufItem without menubuf started\n");
685
686 shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
687 p = (patch_t *)shape;
688
689 if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
690 Error ("DrawMenuBufItem: x is out of range\n");
691 if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
692 Error ("DrawMenuBufItem: y is out of range\n");
693
694 buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
695
696 for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
697 ScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
698 p->topoffset, buffer);
699 }
700
701 //******************************************************************************
702 //
703 // IScaleMenuBufPost
704 //
705 //******************************************************************************
706
IScaleMenuBufPost(byte * src,int topoffset,byte * buf,int color)707 void IScaleMenuBufPost (byte * src, int topoffset, byte * buf, int color)
708 {
709 int d;
710 int offset;
711 int length;
712 int s;
713
714
715 while (1)
716 {
717 offset=*(src++);
718 if (offset==0xff)
719 return;
720 else
721 {
722 d=offset-topoffset;
723 length=*(src++);
724 for (s=0;s<length;s++,d++)
725 *(buf+d)=*(intensitytable+((*(src+s))<<8)+color);
726 src+=length;
727 }
728 }
729 }
730
731
732 //******************************************************************************
733 //
734 // DrawIMenuBufItem
735 //
736 //******************************************************************************
737
DrawIMenuBufItem(int x,int y,int shapenum,int color)738 void DrawIMenuBufItem (int x, int y, int shapenum, int color)
739 {
740 byte *buffer;
741 int cnt;
742 byte *shape;
743 patch_t *p;
744
745
746 if (MenuBufStarted==false)
747 Error("Called DrawIMenuBufItem without menubuf started\n");
748
749 shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
750 p = (patch_t *)shape;
751
752 if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
753 Error ("DrawIMenuBufItem: x is out of range\n");
754 if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
755 Error ("DrawIMenuBufItem: y is out of range\n");
756
757 buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
758
759 for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
760 IScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
761 p->topoffset, buffer, color);
762 }
763
764
765 //******************************************************************************
766 //
767 // TScaleMenuBufPost
768 //
769 //******************************************************************************
TScaleMenuBufPost(byte * src,int topoffset,byte * buf)770 void TScaleMenuBufPost (byte * src, int topoffset, byte * buf)
771 {
772 int d;
773 int offset;
774 int length;
775 byte pixel;
776 int s;
777
778
779 while (1)
780 {
781 offset=*(src++);
782 if (offset==0xff)
783 return;
784 else
785 {
786 d=offset-topoffset;
787 length=*(src++);
788 for (s=0;s<length;s++,d++)
789 {
790 pixel = *(buf+d);
791 pixel = *(shadingtable+pixel);
792 *(buf+d) = pixel;
793 }
794 src+=length;
795 }
796 }
797 }
798
799
800 //******************************************************************************
801 //
802 // CScaleMenuBufPost
803 //
804 //******************************************************************************
CScaleMenuBufPost(byte * src,int topoffset,byte * buf)805 void CScaleMenuBufPost (byte * src, int topoffset, byte * buf)
806 {
807 int d;
808 int offset;
809 int length;
810 byte pixel;
811 int s;
812
813
814 while (1)
815 {
816 offset=*(src++);
817 if (offset==0xff)
818 return;
819 else
820 {
821 d=offset-topoffset;
822 length=*(src++);
823 for (s=0;s<length;s++,d++)
824 {
825 pixel = *(src+s);
826 pixel = *(shadingtable+pixel);
827 *(buf+d) = pixel;
828 }
829 src+=length;
830 }
831 }
832 }
833
834
835 //******************************************************************************
836 //
837 // EraseMenuBufRegion
838 //
839 //******************************************************************************
840
EraseMenuBufRegion(int x,int y,int width,int height)841 void EraseMenuBufRegion (int x, int y, int width, int height)
842 {
843 byte *buffer;
844 int xx,yy;
845 byte * shape;
846
847 if (MenuBufStarted==false)
848 Error("Called EraseMenuBufRegion without menubuf started\n");
849
850 if ((x<0) || (x+width>=TEXTUREW))
851 Error ("EraseMenuBufRegion: x is out of range\n");
852 if ((y<0) || (y+height>=TEXTUREHEIGHT))
853 Error ("EraseMenuBufRegion: y is out of range\n");
854
855 shape=W_CacheLumpName(MENUBACKNAME,PU_CACHE, Cvt_patch_t, 1);
856 shape+=8;
857 shape+=(x*TEXTUREHEIGHT)+y;
858 buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
859
860 for (xx = 0; xx < width; xx++)
861 {
862 for (yy = 0; yy < height; yy++)
863 *(buffer+yy)=*(shape+yy);
864 buffer+=TEXTUREHEIGHT;
865 shape+=TEXTUREHEIGHT;
866 }
867 }
868
869
870 //******************************************************************************
871 //
872 // DrawTMenuBufPic
873 //
874 //******************************************************************************
875
DrawTMenuBufPic(int x,int y,int shapenum)876 void DrawTMenuBufPic (int x, int y, int shapenum)
877 {
878 byte *buffer;
879 byte *buf;
880 int xx,yy;
881 int plane;
882 int pixel;
883 byte *shape;
884 byte *src;
885 pic_t *p;
886
887 if (MenuBufStarted==false)
888 Error("Called DrawTMenuBufPic without menubuf started\n");
889
890 shadingtable=colormap+(25<<8);
891
892 shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_pic_t, 1);
893 p = (pic_t *)shape;
894
895 if ((x<0) || ((x+(p->width<<2))>=TEXTUREW))
896 Error ("DrawTMenuBufPic: x is out of range\n");
897 if ((y<0) || ((y+p->height)>=TEXTUREHEIGHT))
898 Error ("DrawTMenuBufPic: y is out of range\n");
899
900 buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
901
902 src=(byte *)&p->data;
903 for (plane=0;plane<4;plane++,buffer+=TEXTUREHEIGHT)
904 {
905 for (yy = 0; yy < p->height; yy++)
906 {
907 buf=buffer+yy;
908 for (xx = 0; xx < p->width; xx++,buf+=TEXTUREHEIGHT<<2)
909 {
910 pixel = *(buf);
911 pixel = *(shadingtable+pixel);
912 *(buf) = pixel;
913 }
914 }
915 }
916 }
917
918
919 //******************************************************************************
920 //
921 // DrawTMenuBufItem
922 //
923 //******************************************************************************
924
DrawTMenuBufItem(int x,int y,int shapenum)925 void DrawTMenuBufItem (int x, int y, int shapenum)
926 {
927 byte *buffer;
928 int cnt;
929 byte *shape;
930 patch_t *p;
931
932
933 if (MenuBufStarted==false)
934 Error("Called DrawTMenuBufItem without menubuf started\n");
935
936 shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
937 p = (patch_t *)shape;
938
939 shadingtable=colormap+(25<<8);
940
941 if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
942 Error ("DrawTMenuBufItem: x is out of range\n");
943 if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
944 Error ("DrawTMenuBufItem: y is out of range\n");
945
946 buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
947
948 for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
949 TScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
950 p->topoffset, buffer);
951 }
952
953 //******************************************************************************
954 //
955 // DrawColoredMenuBufItem
956 //
957 //******************************************************************************
958
DrawColoredMenuBufItem(int x,int y,int shapenum,int color)959 void DrawColoredMenuBufItem (int x, int y, int shapenum, int color)
960 {
961 byte *buffer;
962 int cnt;
963 byte *shape;
964 patch_t *p;
965
966
967 if (MenuBufStarted==false)
968 Error("Called DrawColoredMenuBufItem without menubuf started\n");
969
970 shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
971 p = (patch_t *)shape;
972
973 shadingtable=playermaps[color]+(16<<8);
974
975 if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
976 Error ("DrawColoredMenuBufItem: x is out of range\n");
977 if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
978 Error ("DrawColoredMenuBufItem: y is out of range\n");
979
980 buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
981
982 for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
983 CScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
984 p->topoffset, buffer);
985 }
986
987 //******************************************************************************
988 //
989 // DrawMenuBufPic
990 //
991 //******************************************************************************
992
DrawMenuBufPic(int x,int y,int shapenum)993 void DrawMenuBufPic (int x, int y, int shapenum)
994 {
995 byte *buffer;
996 byte *buf;
997 int xx,yy;
998 int plane;
999 byte *shape;
1000 byte *src;
1001 pic_t *p;
1002
1003 if (MenuBufStarted==false)
1004 Error("Called DrawMenuBufPic without menubuf started\n");
1005
1006 shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_pic_t, 1);
1007 p = (pic_t *)shape;
1008
1009 if ((x<0) || ((x+(p->width<<2))>=TEXTUREW))
1010 Error ("DrawTMenuBufPic: x is out of range\n");
1011 if ((y<0) || ((y+p->height)>=TEXTUREHEIGHT))
1012 Error ("DrawTMenuBufPic: y is out of range\n");
1013
1014
1015 buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
1016
1017 src=(byte *)&p->data;
1018 for (plane=0;plane<4;plane++,buffer+=TEXTUREHEIGHT)
1019 {
1020 for (yy = 0; yy < p->height; yy++)
1021 {
1022 buf=buffer+yy;
1023 for (xx = 0; xx < p->width; xx++,buf+=TEXTUREHEIGHT<<2)
1024 *(buf)=*(src++);
1025 }
1026 }
1027 }
1028
1029
1030
1031
1032 //******************************************************************************
1033 //
1034 // DrawTMenuBufBox
1035 //
1036 //******************************************************************************
1037
1038
DrawTMenuBufBox(int x,int y,int width,int height)1039 void DrawTMenuBufBox ( int x, int y, int width, int height )
1040 {
1041 byte *buffer;
1042 int xx;
1043 int yy;
1044 int pixel;
1045
1046 if (MenuBufStarted==false)
1047 Error("Called DrawTMenuBufBox without menubuf started\n");
1048
1049 shadingtable = colormap + ( 25 << 8 );
1050
1051 if ( ( x < 0 ) || ( ( x + width ) >= TEXTUREW ) )
1052 Error ("DrawTMenuBar : x is out of range\n");
1053 if ( ( y < 0 ) || ( y + height ) >= TEXTUREHEIGHT )
1054 Error ("DrawTMenuBar : y is out of range\n");
1055
1056 buffer = ( byte * )menubuf + ( x * TEXTUREHEIGHT ) + y;
1057
1058 for ( xx = 0; xx < width; xx++ )
1059 {
1060 for ( yy = 0; yy < height; yy++ )
1061 {
1062 pixel = *( buffer + yy );
1063 pixel = *( shadingtable + pixel );
1064 *( buffer + yy ) = pixel;
1065 }
1066
1067 buffer += TEXTUREHEIGHT;
1068 }
1069 }
1070
1071
1072 //******************************************************************************
1073 //
1074 // DrawTMenuBufHLine
1075 //
1076 //******************************************************************************
1077
DrawTMenuBufHLine(int x,int y,int width,boolean up)1078 void DrawTMenuBufHLine (int x, int y, int width, boolean up)
1079 {
1080 byte *buffer;
1081 byte *buf;
1082 int xx;
1083 int plane;
1084 int pixel;
1085 int w = width>>2;
1086 int ww = w;
1087
1088 if ((x<0) || ((x+(width))>=TEXTUREW))
1089 Error ("DrawTMenuBufBox: x is out of range\n");
1090 if (y<0)
1091 Error ("DrawTMenuBufBox: y is out of range\n");
1092
1093 buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
1094
1095 if (up)
1096 shadingtable=colormap+(13<<8);
1097 else
1098 shadingtable=colormap+(25<<8);
1099
1100 for (plane = 0; plane < 4; plane++, buffer += TEXTUREHEIGHT)
1101 {
1102 w = ww;
1103 switch (plane)
1104 {
1105 case 0:
1106 if (width % 4)
1107 w++;
1108 break;
1109 case 1:
1110 if ((width % 4) > 1)
1111 w++;
1112 break;
1113 case 2:
1114 if ((width % 4) > 2)
1115 w++;
1116 break;
1117 }
1118
1119
1120 buf = buffer;
1121 for (xx = 0; xx < w; xx++, buf += (TEXTUREHEIGHT<<2))
1122 {
1123 pixel = *(buf);
1124 pixel = *(shadingtable+pixel);
1125 *(buf) = pixel;
1126 }
1127 }
1128 }
1129
1130 //******************************************************************************
1131 //
1132 // DrawTMenuBufVLine
1133 //
1134 //******************************************************************************
1135
DrawTMenuBufVLine(int x,int y,int height,boolean up)1136 void DrawTMenuBufVLine (int x, int y, int height, boolean up)
1137 {
1138 byte *buffer;
1139 byte *buf;
1140 int yy;
1141 int pixel;
1142
1143 if (x<0)
1144 Error ("DrawTMenuBufBox: x is out of range\n");
1145 if ((y<0) || ((y+height)>=TEXTUREHEIGHT))
1146 Error ("DrawTMenuBufBox: y is out of range\n");
1147
1148 buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
1149
1150 if (up)
1151 shadingtable=colormap+(13<<8);
1152 else
1153 shadingtable=colormap+(25<<8);
1154
1155 for (yy = 0; yy < height; yy++)
1156 {
1157 buf = buffer+yy;
1158 pixel = *(buf);
1159 pixel = *(shadingtable+pixel);
1160 *(buf) = pixel;
1161 }
1162 }
1163
1164 //******************************************************************************
1165 //******************************************************************************
1166 //
1167 // STRING ROUTINES
1168 //
1169 //******************************************************************************
1170 //******************************************************************************
1171
1172
1173 //******************************************************************************
1174 //
1175 // DrawMenuBufPropString ()
1176 //
1177 //******************************************************************************
1178
DrawMenuBufPropString(int px,int py,const char * string)1179 void DrawMenuBufPropString (int px, int py, const char *string)
1180 {
1181 byte pix;
1182 int width,height,ht;
1183 byte *source, *dest, *origdest;
1184 int ch;
1185
1186
1187 if (MenuBufStarted==false)
1188 Error("Called DrawMenuBufPropString without menubuf started\n");
1189
1190 ht = CurrentFont->height;
1191 dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
1192
1193 while ((ch = (unsigned char)*string++)!=0)
1194 {
1195 ch -= 31;
1196 width = CurrentFont->width[ch];
1197 source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
1198 while (width--)
1199 {
1200 height = ht;
1201 while (height--)
1202 {
1203 pix = *source;
1204 if (pix)
1205 *dest = pix;
1206
1207 source++;
1208 dest ++;
1209 }
1210
1211 PrintX++;
1212 origdest+=TEXTUREHEIGHT;
1213 dest = origdest;
1214 }
1215 }
1216
1217 }
1218
1219
1220 //******************************************************************************
1221 //
1222 // DrawMenuBufIString ()
1223 //
1224 //******************************************************************************
1225
DrawMenuBufIString(int px,int py,const char * string,int color)1226 void DrawMenuBufIString (int px, int py, const char *string, int color)
1227 {
1228 byte pix;
1229 int width,height,ht;
1230 byte *source, *dest, *origdest;
1231 int ch;
1232
1233 if (MenuBufStarted==false)
1234 Error("Called DrawMenuBufPropString without menubuf started\n");
1235
1236 if ( ( color < 0 ) || ( color > 255 ) )
1237 {
1238 Error( "Intensity Color out of range\n" );
1239 }
1240
1241 ht = IFont->height;
1242 dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
1243
1244 PrintX = px;
1245 PrintY = py;
1246
1247 while ((ch = (unsigned char)*string++)!=0)
1248 {
1249 // Tab
1250 if ( ch == '\x9' )
1251 {
1252 int offset;
1253
1254 PrintX -= px;
1255 offset = 4 * 5 - PrintX % ( 4 * 5 );
1256 PrintX += offset + px;
1257 origdest += offset * TEXTUREHEIGHT;
1258 dest = origdest;
1259 continue;
1260 }
1261
1262 ch -= 31;
1263 width = IFont->width[ ch ];
1264
1265 source = ( ( byte * )IFont ) + IFont->charofs[ ch ];
1266
1267 while (width--)
1268 {
1269 height = ht;
1270 while (height--)
1271 {
1272 pix = *source;
1273 if ( pix != 0xFE )
1274 {
1275 *dest = ( ( byte )intensitytable[ ( pix << 8 ) + color ] );
1276 GetIntensityColor( pix );
1277 }
1278
1279 source++;
1280 dest ++;
1281 }
1282
1283 PrintX++;
1284 origdest+=TEXTUREHEIGHT;
1285 dest = origdest;
1286 }
1287 }
1288
1289 }
1290
1291
1292 //******************************************************************************
1293 //
1294 // DrawTMenuBufPropString ()
1295 //
1296 // Draws a string at px, py to bufferofs
1297 //
1298 //******************************************************************************
1299
DrawTMenuBufPropString(int px,int py,const char * string)1300 void DrawTMenuBufPropString (int px, int py, const char *string)
1301 {
1302 byte pix;
1303 int width,height,ht;
1304 byte *source, *dest, *origdest;
1305 int ch;
1306
1307
1308 if (MenuBufStarted==false)
1309 Error("Called DrawTMenuBufPropString without menubuf started\n");
1310
1311 ht = CurrentFont->height;
1312 dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
1313
1314 shadingtable=colormap+(StringShade<<8);
1315 while ((ch = (unsigned char)*string++)!=0)
1316 {
1317 ch -= 31;
1318 width = CurrentFont->width[ch];
1319 source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
1320 while (width--)
1321 {
1322 height = ht;
1323 while (height--)
1324 {
1325 pix = *source;
1326 if (pix)
1327 {
1328 pix = *dest;
1329 pix = *(shadingtable+pix);
1330 *dest = pix;
1331 }
1332 source++;
1333 dest ++;
1334 }
1335
1336 PrintX++;
1337 origdest+=TEXTUREHEIGHT;
1338 dest = origdest;
1339 }
1340 }
1341 }
1342
1343
1344 //******************************************************************************
1345 //
1346 // MenuBufCPrintLine() - Prints a string centered on the current line and
1347 // advances to the next line. Newlines are not supported.
1348 //
1349 //******************************************************************************
1350
MenuBufCPrintLine(const char * s)1351 void MenuBufCPrintLine (const char *s)
1352 {
1353 int w, h;
1354
1355 USL_MeasureString (s, &w, &h, CurrentFont);
1356
1357 if (w > WindowW)
1358 Error("MenuBufCPrintLine() - String exceeds width");
1359
1360 PrintX = WindowX + ((WindowW - w) / 2);
1361 DrawMenuBufPropString (PrintX, PrintY, s);
1362 PrintY += h;
1363 }
1364
1365 //******************************************************************************
1366 //
1367 // MenuBufCPrint() - Prints a string in the current window. Newlines are
1368 // supported.
1369 //
1370 //******************************************************************************
1371
MenuBufCPrint(const char * string)1372 void MenuBufCPrint (const char *string)
1373 {
1374 char c,
1375 *se,
1376 *s;
1377
1378 /* !!! FIXME: this is lame. */
1379 if (strlen(string) >= sizeof (strbuf))
1380 {
1381 fprintf(stderr, "buffer overflow!\n");
1382 return;
1383 }
1384
1385 /* prevent writing to literal strings... ( MenubufCPrint("feh"); ) */
1386 strcpy(strbuf, string);
1387 s = strbuf;
1388
1389 while (*s)
1390 {
1391 se = s;
1392 while ((c = *se) && (c != '\n'))
1393 se++;
1394 *se = '\0';
1395
1396 MenuBufCPrintLine(s);
1397
1398 s = se;
1399 if (c)
1400 {
1401 *se = c;
1402 s++;
1403 }
1404 }
1405 }
1406
1407 //******************************************************************************
1408 //
1409 // MenuBufPrintLine() - Prints a string on the current line and
1410 // advances to the next line. Newlines are not supported.
1411 //
1412 //******************************************************************************
1413
MenuBufPrintLine(const char * s)1414 void MenuBufPrintLine (const char *s)
1415 {
1416 int w, h;
1417
1418 USL_MeasureString (s, &w, &h, CurrentFont);
1419
1420 if (w > WindowW)
1421 Error("MenuBufCPrintLine() - String exceeds width");
1422
1423 PrintX = WindowX;
1424 DrawMenuBufPropString (PrintX, PrintY, s);
1425 PrintY += h;
1426 }
1427
1428 //******************************************************************************
1429 //
1430 // MenuBufPrint() - Prints a string in the current window. Newlines are
1431 // supported.
1432 //
1433 //******************************************************************************
1434
MenuBufPrint(const char * string)1435 void MenuBufPrint (const char *string)
1436 {
1437 char c,
1438 *se,
1439 *s;
1440
1441 strcpy(strbuf, string);
1442 s = strbuf;
1443
1444 while (*s)
1445 {
1446 se = s;
1447 while ((c = *se) && (c != '\n'))
1448 se++;
1449 *se = '\0';
1450
1451 MenuBufPrintLine(s);
1452
1453 s = se;
1454 if (c)
1455 {
1456 *se = c;
1457 s++;
1458 }
1459 }
1460 }
1461
1462 //******************************************************************************
1463 //
1464 // MenuTBufPrintLine() - Prints a string on the current line and
1465 // advances to the next line. Newlines are not supported.
1466 //
1467 //******************************************************************************
1468
MenuTBufPrintLine(const char * s,int shade)1469 void MenuTBufPrintLine (const char *s, int shade)
1470 {
1471 int w, h;
1472
1473 USL_MeasureString (s, &w, &h, CurrentFont);
1474
1475 if (w > WindowW)
1476 Error("MenuBufCPrintLine() - String exceeds width");
1477
1478 PrintX = WindowX;
1479 StringShade=shade;
1480 DrawTMenuBufPropString (PrintX, PrintY, s);
1481 PrintY += h;
1482 }
1483
1484 //******************************************************************************
1485 //
1486 // FlipMenuBuf
1487 //
1488 //******************************************************************************
1489
FlipMenuBuf(void)1490 void FlipMenuBuf ( void )
1491 {
1492 int i;
1493 int dh;
1494 int h;
1495 int y;
1496 int dy;
1497 int time;
1498 int flip;
1499
1500 if (MenuBufStarted==false)
1501 Error("Called FlipMenuBuf without menubuf started\n");
1502
1503 if (!readytoflip)
1504 Error("FlipMenuBuf called without SetAlternateMenuBuf beforehand");
1505 readytoflip=0;
1506 if (Menuflipspeed<=5)
1507 {
1508 menubuf=menubuffers[alternatemenubuf];
1509 strcpy(titlestring,menutitles[alternatemenubuf]);
1510 RefreshMenuBuf(0);
1511 }
1512 else
1513 {
1514 menubuf=menubuffers[alternatemenubuf^1];
1515 strcpy(titlestring,menutitles[alternatemenubuf^1]);
1516 time=Menuflipspeed-5;
1517 dh=(1024<<8)/time;
1518 h=0;
1519 dy=((MENUTITLEY*6)<<8)/time;
1520 y=0;
1521 flip=0;
1522 titleyoffset=0;
1523 for (i=0;i<time;i+=tics)
1524 {
1525 PositionMenuBuf(h>>8,NORMALVIEW,true);
1526 h+=dh*tics;
1527 y+=dy*tics;
1528 titleyoffset=y>>8;
1529 if ((h>=512<<8) && (flip==0))
1530 {
1531 MN_PlayMenuSnd (SD_MENUFLIP);
1532 h=1536<<8;
1533 dy=-dy;
1534 menubuf=menubuffers[alternatemenubuf];
1535 strcpy(titlestring,menutitles[alternatemenubuf]);
1536 flip=1;
1537 }
1538 }
1539 }
1540 titleyoffset=0;
1541 BackgroundDrawn=false;
1542 }
1543
1544
1545
1546 //******************************************************************************
1547 //
1548 // RotatePlane
1549 //
1550 //******************************************************************************
1551
RotatePlane(void)1552 void RotatePlane ( void )
1553 {
1554 SetupMenuBuf();
1555
1556 while (!(Keyboard[0x01]))
1557 {
1558 RefreshMenuBuf(100);
1559 SetAlternateMenuBuf();
1560 ClearMenuBuf();
1561 DrawMenuBufPic (0,0,W_GetNumForName("newg11"));
1562 DrawMenuBufItem (0,0,W_GetNumForName("apogee"));
1563 FlipMenuBuf();
1564 EraseMenuBufRegion(30,30,30,30);
1565 RefreshMenuBuf(100);
1566 SetAlternateMenuBuf();
1567 ClearMenuBuf();
1568 FlipMenuBuf();
1569 }
1570 ShutdownMenuBuf();
1571 }
1572