rott/rott/rt_build.c

1573 lines
36 KiB
C
Executable File

/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// RT_BUILD.C
#include "rt_def.h"
#include <string.h>
#include "watcom.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef DOS
#include <dos.h>
#include <conio.h>
#endif
#include "rt_build.h"
#include "_rt_buil.h"
#include "rt_dr_a.h"
#include "rt_draw.h"
#include "rt_scale.h"
#include "rt_menu.h"
#include "rt_main.h"
#include "isr.h"
#include "rt_util.h"
#include "engine.h"
#include "lumpy.h"
#include "rt_fc_a.h"
#include "z_zone.h"
#include "w_wad.h"
#include "rt_view.h"
#include "rt_cfg.h"
#include "rt_vid.h"
#include "rt_sound.h"
#include "modexlib.h"
#include "rt_str.h"
//MED
#include "memcheck.h"
byte * intensitytable;
// LOCAL VARIABLES
static byte * menubuf;
static byte * menubuffers[2];
static char menutitles[2][40];
static int alternatemenubuf=0;
static int titleshade=16;
static int titleshadedir=1;
static int titleyoffset=0;
static char titlestring[40]="\0";
static int readytoflip;
static boolean MenuBufStarted=false;
static int mindist=0x2700;
static boolean BackgroundDrawn=false;
static plane_t planelist[MAXPLANES],*planeptr;
static int StringShade=16;
extern void (*USL_MeasureString)(const char *, int *, int *, font_t *);
static char strbuf[MaxString];
//******************************************************************************
//
// DrawRotPost
//
//******************************************************************************
void DrawRotPost ( int height, byte * src, byte * buf, int origheight)
{
int y1;
int y2;
hp_srcstep=(origheight<<18)/height;
y1 = (((centery<<8)-(height<<5)+(MENUOFFY<<8)));
y2 = (((height<<6)+y1)>>8);
if (((y1>>8)>=200) || (y2<0))
return;
if (y1<0)
{
hp_startfrac=FixedMulShift(-y1,hp_srcstep,8);
y2 = (((height<<6)+y1)>>8);
y1=0;
}
else
{
hp_startfrac=FixedMulShift(255-(y1&0xff),hp_srcstep,8);
y1>>=8;
}
if (y2>200)
{
DrawMenuPost(200-y1, src, buf+ylookup[y1]);
}
else
{
DrawMenuPost(y2-y1, src, buf+ylookup[y1]);
}
}
/*
========================
=
= GetPoint
=
========================
*/
void GetPoint (int x1, int y1, int px, int py, int * screenx, int * height, int angle)
{
fixed gxt,gyt,nx,ny;
fixed gxtt,gytt;
int gx,gy;
//
// translate point to view centered coordinates
//
gx = x1-px;
gy = y1-py;
//
// calculate newx
//
gxt = FixedMul(gx,costable[angle]);
gyt = FixedMul(gy,sintable[angle]);
nx =gxt-gyt;
if (nx<mindist)
nx=mindist;
//
// calculate newy
//
gxtt = FixedMul(gx,sintable[angle]);
gytt = FixedMul(gy,costable[angle]);
ny = gytt+gxtt;
// too close, don't overflow the divid'
*screenx = 160 + ((ny*NORMALWIDTHMULTIPLIER)/nx); // DEBUG: use assembly divide
*height = NORMALHEIGHTDIVISOR/nx;
if (*screenx<0) *screenx=0;
}
/*
========================
=
= InterpolatePlane
=
========================
*/
void InterpolatePlane (visobj_t * plane)
{
int d1,d2;
int top;
int topinc;
int bot;
int botinc;
int i;
int texture;
int dh;
int dx;
int height;
dx=(plane->x2-plane->x1+1);
if (plane->h1<=0 || plane->h2<=0 || (dx==0))
return;
d1=65536/plane->h1;
d2=65536/plane->h2;
dh=((plane->h2-plane->h1)<<8)/dx;
top=0;
topinc=(d1)*((plane->textureend-plane->texturestart)>>4);
bot=d2*dx;
botinc=d1-d2;
height=(plane->h1<<8);
if (plane->x1>=viewwidth)
return;
for (i=plane->x1;i<=plane->x2;i++)
{
if ((i>=0 && i<viewwidth)&&(posts[i].wallheight<(height>>8)))
{
if (bot)
{
texture=((top/bot)+(plane->texturestart>>4))>>6;
posts[i].texture=texture*plane->viewx;
posts[i].lump=plane->shapenum;
posts[i].wallheight=(height>>8);
posts[i].offset=plane->viewx;
}
}
top+=topinc;
bot+=botinc;
height+=dh;
}
}
//******************************************************************************
//
// DrawPlanePosts
//
//******************************************************************************
void DrawPlanePosts (void)
{
int height;
char * buf;
byte * shape;
int lastwall=-2;
int plane;
int i;
shadingtable=colormap+(16<<8);
#ifdef DOS
for (plane=0;plane<4;plane++)
#endif
{
VGAWRITEMAP(plane);
buf=(byte *)(bufferofs);
#ifdef DOS
for (i=plane;i<viewwidth;i+=4,buf++)
#else
for (i=0;i<viewwidth;i++,buf++)
#endif
{
height=(posts[i].wallheight);
if (height<=4)
continue;
if (lastwall!=posts[i].lump)
{
lastwall=posts[i].lump;
if (lastwall==-1)
shape=menubuf;
else
shape=W_CacheLumpNum(lastwall,PU_CACHE, Cvt_patch_t, 1);
}
DrawRotPost (height,shape+posts[i].texture,buf,posts[i].offset);
}
}
}
//******************************************************************************
//
// NextPlaneptr
//
//******************************************************************************
void NextPlaneptr ( void )
{
if (planeptr < &planelist[MAXPLANES-1]) // don't let it overflo'
planeptr++;
}
//******************************************************************************
//
// RestPlaneptr
//
//******************************************************************************
void ResetPlaneptr ( void )
{
planeptr = &planelist[0];
}
//******************************************************************************
//
// NextVisptr
//
//******************************************************************************
void NextVisptr ( void )
{
if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
visptr++;
}
//******************************************************************************
//
// ResetVisptr
//
//******************************************************************************
void ResetVisptr ( void )
{
visptr = &vislist[0];
}
//******************************************************************************
//
// SetupPlanes
//
//******************************************************************************
void SetupPlanes ( void )
{
int i;
for (i=0;i<320;i++)
posts[i].wallheight=-1;
}
//******************************************************************************
//
// CalcPlanes
//
//******************************************************************************
void CalcPlanes ( int px, int py, int angle )
{
plane_t * pptr;
ResetVisptr();
for (pptr = &planelist[0]; pptr<planeptr; pptr++)
{
if (SideOfLine(pptr->x1,pptr->y1,pptr->x2,pptr->y2,px,py)<0)
{
GetPoint (pptr->x1,pptr->y1,px,py,&visptr->x1,&visptr->h1,angle);
GetPoint (pptr->x2,pptr->y2,px,py,&visptr->x2,&visptr->h2,angle);
visptr->textureend=0x0;
visptr->texturestart=pptr->texturewidth;
}
else
{
GetPoint (pptr->x2,pptr->y2,px,py,&visptr->x1,&visptr->h1,angle);
GetPoint (pptr->x1,pptr->y1,px,py,&visptr->x2,&visptr->h2,angle);
visptr->texturestart=0x0;
visptr->textureend=pptr->texturewidth;
}
visptr->shapenum=pptr->texture;
visptr->viewx=pptr->origheight;
visptr->viewheight=MAX(visptr->h1,visptr->h2);
NextVisptr();
}
}
//******************************************************************************
//
// DrawTransformedPlanes
//
//******************************************************************************
void DrawTransformedPlanes ( void )
{
int numvisible;
int greatest;
int height;
int i;
visobj_t * closest;
numvisible = visptr-&vislist[0];
if (!numvisible)
return; // no visible objects
for (i = 0; i<numvisible; i++)
{
greatest = 0;
for (visstep=&vislist[0] ; visstep<visptr ; visstep++)
{
height = visstep->viewheight;
if (height > greatest)
{
greatest = height;
closest = visstep;
}
}
InterpolatePlane(closest);
closest->viewheight = 0;
}
}
//******************************************************************************
//
// ClearMenuBuf
//
//******************************************************************************
void ClearMenuBuf ( void )
{
byte * shape;
if (MenuBufStarted==false)
Error("Called ClearMenuBuf without menubuf started\n");
shape=W_CacheLumpName(MENUBACKNAME,PU_CACHE, Cvt_patch_t, 1);
shape+=8;
memcpy (menubuf,shape,TEXTUREW*TEXTUREHEIGHT);
}
//******************************************************************************
//
// ShutdownMenuBuf
//
//******************************************************************************
void ShutdownMenuBuf ( void )
{
if (MenuBufStarted==false)
return;
MenuBufStarted=false;
SafeFree(menubuffers[0]);
SafeFree(menubuffers[1]);
if (loadedgame==false)
SetViewSize(viewsize);
}
//******************************************************************************
//
// SetupMenuBuf
//
//******************************************************************************
void SetupMenuBuf ( void )
{
#define SRCH 148
#define SRCW 258
#define PLANEX1 (-0x24000)
#define PLANEX2 (0x23fff)
#define PLANEW (16<<10)
#define PLANEY (0x40000)
#define PLANEW2 (0x5a827)
if (MenuBufStarted==true)
return;
MenuBufStarted=true;
// No top offsets like in game
centery=100;
centeryfrac=centery<<16;
strcpy(titlestring,menutitles[0]);
screenofs=0;
viewwidth=320;
viewheight=200;
alternatemenubuf=0;
ResetPlaneptr();
planeptr->texture=-1;
planeptr->y1=PLANEX1;
planeptr->x1=PLANEW;
planeptr->y2=PLANEX2;
planeptr->x2=PLANEW;
planeptr->origheight=TEXTUREHEIGHT;
planeptr->texturewidth=TEXTUREWIDTH;
NextPlaneptr();
planeptr->texture=-1;
planeptr->y1=PLANEX1;
planeptr->x1=-PLANEW;
planeptr->y2=PLANEX2;
planeptr->x2=-PLANEW;
planeptr->origheight=TEXTUREHEIGHT;
planeptr->texturewidth=TEXTUREWIDTH;
NextPlaneptr();
planeptr->texture=W_GetNumForName(MENUBACKNAME);
planeptr->y1=PLANEX1;
planeptr->x1=PLANEW;
planeptr->y2=PLANEX1;
planeptr->x2=-PLANEW;
planeptr->origheight=TEXTUREHEIGHT;
planeptr->texturewidth=TEXTUREWIDTH;
NextPlaneptr();
planeptr->texture=W_GetNumForName(MENUBACKNAME);
planeptr->y1=PLANEX2;
planeptr->x1=PLANEW;
planeptr->y2=PLANEX2;
planeptr->x2=-PLANEW;
planeptr->origheight=TEXTUREHEIGHT;
planeptr->texturewidth=TEXTUREWIDTH;
NextPlaneptr();
menubuffers[0]=SafeMalloc(TEXTUREW*TEXTUREHEIGHT);
menubuffers[1]=SafeMalloc(TEXTUREW*TEXTUREHEIGHT);
menubuf=menubuffers[0];
ClearMenuBuf();
BackgroundDrawn=false;
}
//******************************************************************************
//
// PositionMenuBuf
//
//******************************************************************************
void PositionMenuBuf( int angle, int distance, boolean drawbackground )
{
int px,py;
font_t * oldfont;
int width,height;
if (MenuBufStarted==false)
Error("Called PositionMenuBuf without menubuf started\n");
CalcTics();
SetupPlanes();
if ((drawbackground==true) || (BackgroundDrawn==false))
{
VL_DrawPostPic (W_GetNumForName("trilogo"));
}
px=FixedMulShift(distance,costable[angle&(FINEANGLES-1)],16);
py=FixedMulShift(-distance,sintable[angle&(FINEANGLES-1)],16);
CalcPlanes(px,py,(angle+ANG180)&(FINEANGLES-1));
DrawTransformedPlanes();
DrawPlanePosts();
oldfont=CurrentFont;
CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
US_MeasureStr (&width, &height, "%s", titlestring);
US_ClippedPrint ((320-width)>>1, MENUTITLEY-titleyoffset, titlestring);
CurrentFont=oldfont;
FlipPage();
titleshade+=titleshadedir;
if (abs(titleshade-16)>6)
titleshadedir=-titleshadedir;
if (BackgroundDrawn==false)
{
VL_CopyDisplayToHidden();
BackgroundDrawn=true;
}
}
//******************************************************************************
//
// RefreshMenuBuf
//
//******************************************************************************
void RefreshMenuBuf( int time )
{
int i;
if (MenuBufStarted==false)
Error("Called RefreshMenuBuf without menubuf started\n");
if (readytoflip)
return;
for (i=0;i<=time;i+=tics)
{
//PositionMenuBuf (0,NORMALVIEW,false);
PositionMenuBuf (0,NORMALVIEW,true);//bna++ in not true bg in menu is no redrawn
}
}
//******************************************************************************
//
// ScaleMenuBufPost
//
//******************************************************************************
void ScaleMenuBufPost (byte * src, int topoffset, byte * buf)
{
int d;
int offset;
int length;
int s;
while (1)
{
offset=*(src++);
if (offset==0xff)
return;
else
{
d=offset-topoffset;
length=*(src++);
for (s=0;s<length;s++,d++)
*(buf+d)=*(src+s);
src+=length;
}
}
}
//******************************************************************************
//
// SetAlternateMenuBuf
//
//******************************************************************************
void SetAlternateMenuBuf ( void )
{
if (MenuBufStarted==false)
Error("Called SetAlternateMenuBuf without menubuf started\n");
alternatemenubuf^=1;
readytoflip=1;
menubuf=menubuffers[alternatemenubuf];
}
//******************************************************************************
//
// SetMenuTitle
//
//******************************************************************************
void SetMenuTitle ( const char * menutitle )
{
if (MenuBufStarted==false)
Error("Called SetMenuTitle without menubuf started\n");
strcpy(menutitles[alternatemenubuf],menutitle);
if (readytoflip==0)
strcpy(titlestring,menutitle);
}
//******************************************************************************
//
// DrawMenuBufPicture
//
//******************************************************************************
void DrawMenuBufPicture (int x, int y, const byte * pic, int w, int h)
{
byte *buffer;
int i;
if (MenuBufStarted==false)
Error("Called DrawMenuBufPictoure without menubuf started\n");
if ((x<0) || (x+w>=TEXTUREW))
Error ("DrawMenuBufPicture: x is out of range\n");
if ((y<0) || (y+h>=TEXTUREHEIGHT))
Error ("DrawMenuBufPicture: y is out of range\n");
for (i=0;i<w;i++)
{
buffer = (byte*)menubuf+y+((x+i)*TEXTUREHEIGHT);
memcpy(buffer,pic,h);
pic+=h;
}
}
//******************************************************************************
//
// DrawMenuBufItem
//
//******************************************************************************
void DrawMenuBufItem (int x, int y, int shapenum)
{
byte *buffer;
int cnt;
byte *shape;
patch_t *p;
if (MenuBufStarted==false)
Error("Called DrawMenuBufItem without menubuf started\n");
shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
p = (patch_t *)shape;
if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
Error ("DrawMenuBufItem: x is out of range\n");
if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
Error ("DrawMenuBufItem: y is out of range\n");
buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
ScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
p->topoffset, buffer);
}
//******************************************************************************
//
// IScaleMenuBufPost
//
//******************************************************************************
void IScaleMenuBufPost (byte * src, int topoffset, byte * buf, int color)
{
int d;
int offset;
int length;
int s;
while (1)
{
offset=*(src++);
if (offset==0xff)
return;
else
{
d=offset-topoffset;
length=*(src++);
for (s=0;s<length;s++,d++)
*(buf+d)=*(intensitytable+((*(src+s))<<8)+color);
src+=length;
}
}
}
//******************************************************************************
//
// DrawIMenuBufItem
//
//******************************************************************************
void DrawIMenuBufItem (int x, int y, int shapenum, int color)
{
byte *buffer;
int cnt;
byte *shape;
patch_t *p;
if (MenuBufStarted==false)
Error("Called DrawIMenuBufItem without menubuf started\n");
shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
p = (patch_t *)shape;
if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
Error ("DrawIMenuBufItem: x is out of range\n");
if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
Error ("DrawIMenuBufItem: y is out of range\n");
buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
IScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
p->topoffset, buffer, color);
}
//******************************************************************************
//
// TScaleMenuBufPost
//
//******************************************************************************
void TScaleMenuBufPost (byte * src, int topoffset, byte * buf)
{
int d;
int offset;
int length;
byte pixel;
int s;
while (1)
{
offset=*(src++);
if (offset==0xff)
return;
else
{
d=offset-topoffset;
length=*(src++);
for (s=0;s<length;s++,d++)
{
pixel = *(buf+d);
pixel = *(shadingtable+pixel);
*(buf+d) = pixel;
}
src+=length;
}
}
}
//******************************************************************************
//
// CScaleMenuBufPost
//
//******************************************************************************
void CScaleMenuBufPost (byte * src, int topoffset, byte * buf)
{
int d;
int offset;
int length;
byte pixel;
int s;
while (1)
{
offset=*(src++);
if (offset==0xff)
return;
else
{
d=offset-topoffset;
length=*(src++);
for (s=0;s<length;s++,d++)
{
pixel = *(src+s);
pixel = *(shadingtable+pixel);
*(buf+d) = pixel;
}
src+=length;
}
}
}
//******************************************************************************
//
// EraseMenuBufRegion
//
//******************************************************************************
void EraseMenuBufRegion (int x, int y, int width, int height)
{
byte *buffer;
int xx,yy;
byte * shape;
if (MenuBufStarted==false)
Error("Called EraseMenuBufRegion without menubuf started\n");
if ((x<0) || (x+width>=TEXTUREW))
Error ("EraseMenuBufRegion: x is out of range\n");
if ((y<0) || (y+height>=TEXTUREHEIGHT))
Error ("EraseMenuBufRegion: y is out of range\n");
shape=W_CacheLumpName(MENUBACKNAME,PU_CACHE, Cvt_patch_t, 1);
shape+=8;
shape+=(x*TEXTUREHEIGHT)+y;
buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
for (xx = 0; xx < width; xx++)
{
for (yy = 0; yy < height; yy++)
*(buffer+yy)=*(shape+yy);
buffer+=TEXTUREHEIGHT;
shape+=TEXTUREHEIGHT;
}
}
//******************************************************************************
//
// DrawTMenuBufPic
//
//******************************************************************************
void DrawTMenuBufPic (int x, int y, int shapenum)
{
byte *buffer;
byte *buf;
int xx,yy;
int plane;
int pixel;
byte *shape;
byte *src;
pic_t *p;
if (MenuBufStarted==false)
Error("Called DrawTMenuBufPic without menubuf started\n");
shadingtable=colormap+(25<<8);
shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_pic_t, 1);
p = (pic_t *)shape;
if ((x<0) || ((x+(p->width<<2))>=TEXTUREW))
Error ("DrawTMenuBufPic: x is out of range\n");
if ((y<0) || ((y+p->height)>=TEXTUREHEIGHT))
Error ("DrawTMenuBufPic: y is out of range\n");
buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
src=(byte *)&p->data;
for (plane=0;plane<4;plane++,buffer+=TEXTUREHEIGHT)
{
for (yy = 0; yy < p->height; yy++)
{
buf=buffer+yy;
for (xx = 0; xx < p->width; xx++,buf+=TEXTUREHEIGHT<<2)
{
pixel = *(buf);
pixel = *(shadingtable+pixel);
*(buf) = pixel;
}
}
}
}
//******************************************************************************
//
// DrawTMenuBufItem
//
//******************************************************************************
void DrawTMenuBufItem (int x, int y, int shapenum)
{
byte *buffer;
int cnt;
byte *shape;
patch_t *p;
if (MenuBufStarted==false)
Error("Called DrawTMenuBufItem without menubuf started\n");
shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
p = (patch_t *)shape;
shadingtable=colormap+(25<<8);
if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
Error ("DrawTMenuBufItem: x is out of range\n");
if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
Error ("DrawTMenuBufItem: y is out of range\n");
buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
TScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
p->topoffset, buffer);
}
//******************************************************************************
//
// DrawColoredMenuBufItem
//
//******************************************************************************
void DrawColoredMenuBufItem (int x, int y, int shapenum, int color)
{
byte *buffer;
int cnt;
byte *shape;
patch_t *p;
if (MenuBufStarted==false)
Error("Called DrawColoredMenuBufItem without menubuf started\n");
shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
p = (patch_t *)shape;
shadingtable=playermaps[color]+(16<<8);
if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
Error ("DrawColoredMenuBufItem: x is out of range\n");
if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
Error ("DrawColoredMenuBufItem: y is out of range\n");
buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
CScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
p->topoffset, buffer);
}
//******************************************************************************
//
// DrawMenuBufPic
//
//******************************************************************************
void DrawMenuBufPic (int x, int y, int shapenum)
{
byte *buffer;
byte *buf;
int xx,yy;
int plane;
byte *shape;
byte *src;
pic_t *p;
if (MenuBufStarted==false)
Error("Called DrawMenuBufPic without menubuf started\n");
shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_pic_t, 1);
p = (pic_t *)shape;
if ((x<0) || ((x+(p->width<<2))>=TEXTUREW))
Error ("DrawTMenuBufPic: x is out of range\n");
if ((y<0) || ((y+p->height)>=TEXTUREHEIGHT))
Error ("DrawTMenuBufPic: y is out of range\n");
buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
src=(byte *)&p->data;
for (plane=0;plane<4;plane++,buffer+=TEXTUREHEIGHT)
{
for (yy = 0; yy < p->height; yy++)
{
buf=buffer+yy;
for (xx = 0; xx < p->width; xx++,buf+=TEXTUREHEIGHT<<2)
*(buf)=*(src++);
}
}
}
//******************************************************************************
//
// DrawTMenuBufBox
//
//******************************************************************************
void DrawTMenuBufBox ( int x, int y, int width, int height )
{
byte *buffer;
int xx;
int yy;
int pixel;
if (MenuBufStarted==false)
Error("Called DrawTMenuBufBox without menubuf started\n");
shadingtable = colormap + ( 25 << 8 );
if ( ( x < 0 ) || ( ( x + width ) >= TEXTUREW ) )
Error ("DrawTMenuBar : x is out of range\n");
if ( ( y < 0 ) || ( y + height ) >= TEXTUREHEIGHT )
Error ("DrawTMenuBar : y is out of range\n");
buffer = ( byte * )menubuf + ( x * TEXTUREHEIGHT ) + y;
for ( xx = 0; xx < width; xx++ )
{
for ( yy = 0; yy < height; yy++ )
{
pixel = *( buffer + yy );
pixel = *( shadingtable + pixel );
*( buffer + yy ) = pixel;
}
buffer += TEXTUREHEIGHT;
}
}
//******************************************************************************
//
// DrawTMenuBufHLine
//
//******************************************************************************
void DrawTMenuBufHLine (int x, int y, int width, boolean up)
{
byte *buffer;
byte *buf;
int xx;
int plane;
int pixel;
int w = width>>2;
int ww = w;
if ((x<0) || ((x+(width))>=TEXTUREW))
Error ("DrawTMenuBufBox: x is out of range\n");
if (y<0)
Error ("DrawTMenuBufBox: y is out of range\n");
buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
if (up)
shadingtable=colormap+(13<<8);
else
shadingtable=colormap+(25<<8);
for (plane = 0; plane < 4; plane++, buffer += TEXTUREHEIGHT)
{
w = ww;
switch (plane)
{
case 0:
if (width % 4)
w++;
break;
case 1:
if ((width % 4) > 1)
w++;
break;
case 2:
if ((width % 4) > 2)
w++;
break;
}
buf = buffer;
for (xx = 0; xx < w; xx++, buf += (TEXTUREHEIGHT<<2))
{
pixel = *(buf);
pixel = *(shadingtable+pixel);
*(buf) = pixel;
}
}
}
//******************************************************************************
//
// DrawTMenuBufVLine
//
//******************************************************************************
void DrawTMenuBufVLine (int x, int y, int height, boolean up)
{
byte *buffer;
byte *buf;
int yy;
int pixel;
if (x<0)
Error ("DrawTMenuBufBox: x is out of range\n");
if ((y<0) || ((y+height)>=TEXTUREHEIGHT))
Error ("DrawTMenuBufBox: y is out of range\n");
buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
if (up)
shadingtable=colormap+(13<<8);
else
shadingtable=colormap+(25<<8);
for (yy = 0; yy < height; yy++)
{
buf = buffer+yy;
pixel = *(buf);
pixel = *(shadingtable+pixel);
*(buf) = pixel;
}
}
//******************************************************************************
//******************************************************************************
//
// STRING ROUTINES
//
//******************************************************************************
//******************************************************************************
//******************************************************************************
//
// DrawMenuBufPropString ()
//
//******************************************************************************
void DrawMenuBufPropString (int px, int py, const char *string)
{
byte pix;
int width,height,ht;
byte *source, *dest, *origdest;
int ch;
if (MenuBufStarted==false)
Error("Called DrawMenuBufPropString without menubuf started\n");
ht = CurrentFont->height;
dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
while ((ch = (unsigned char)*string++)!=0)
{
ch -= 31;
width = CurrentFont->width[ch];
source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
while (width--)
{
height = ht;
while (height--)
{
pix = *source;
if (pix)
*dest = pix;
source++;
dest ++;
}
PrintX++;
origdest+=TEXTUREHEIGHT;
dest = origdest;
}
}
}
//******************************************************************************
//
// DrawMenuBufIString ()
//
//******************************************************************************
void DrawMenuBufIString (int px, int py, const char *string, int color)
{
byte pix;
int width,height,ht;
byte *source, *dest, *origdest;
int ch;
if (MenuBufStarted==false)
Error("Called DrawMenuBufPropString without menubuf started\n");
if ( ( color < 0 ) || ( color > 255 ) )
{
Error( "Intensity Color out of range\n" );
}
ht = IFont->height;
dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
PrintX = px;
PrintY = py;
while ((ch = (unsigned char)*string++)!=0)
{
// Tab
if ( ch == '\x9' )
{
int offset;
PrintX -= px;
offset = 4 * 5 - PrintX % ( 4 * 5 );
PrintX += offset + px;
origdest += offset * TEXTUREHEIGHT;
dest = origdest;
continue;
}
ch -= 31;
width = IFont->width[ ch ];
source = ( ( byte * )IFont ) + IFont->charofs[ ch ];
while (width--)
{
height = ht;
while (height--)
{
pix = *source;
if ( pix != 0xFE )
{
*dest = ( ( byte )intensitytable[ ( pix << 8 ) + color ] );
GetIntensityColor( pix );
}
source++;
dest ++;
}
PrintX++;
origdest+=TEXTUREHEIGHT;
dest = origdest;
}
}
}
//******************************************************************************
//
// DrawTMenuBufPropString ()
//
// Draws a string at px, py to bufferofs
//
//******************************************************************************
void DrawTMenuBufPropString (int px, int py, const char *string)
{
byte pix;
int width,height,ht;
byte *source, *dest, *origdest;
int ch;
if (MenuBufStarted==false)
Error("Called DrawTMenuBufPropString without menubuf started\n");
ht = CurrentFont->height;
dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
shadingtable=colormap+(StringShade<<8);
while ((ch = (unsigned char)*string++)!=0)
{
ch -= 31;
width = CurrentFont->width[ch];
source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
while (width--)
{
height = ht;
while (height--)
{
pix = *source;
if (pix)
{
pix = *dest;
pix = *(shadingtable+pix);
*dest = pix;
}
source++;
dest ++;
}
PrintX++;
origdest+=TEXTUREHEIGHT;
dest = origdest;
}
}
}
//******************************************************************************
//
// MenuBufCPrintLine() - Prints a string centered on the current line and
// advances to the next line. Newlines are not supported.
//
//******************************************************************************
void MenuBufCPrintLine (const char *s)
{
int w, h;
USL_MeasureString (s, &w, &h, CurrentFont);
if (w > WindowW)
Error("MenuBufCPrintLine() - String exceeds width");
PrintX = WindowX + ((WindowW - w) / 2);
DrawMenuBufPropString (PrintX, PrintY, s);
PrintY += h;
}
//******************************************************************************
//
// MenuBufCPrint() - Prints a string in the current window. Newlines are
// supported.
//
//******************************************************************************
void MenuBufCPrint (const char *string)
{
char c,
*se,
*s;
/* !!! FIXME: this is lame. */
if (strlen(string) >= sizeof (strbuf))
{
fprintf(stderr, "buffer overflow!\n");
return;
}
/* prevent writing to literal strings... ( MenubufCPrint("feh"); ) */
strcpy(strbuf, string);
s = strbuf;
while (*s)
{
se = s;
while ((c = *se) && (c != '\n'))
se++;
*se = '\0';
MenuBufCPrintLine(s);
s = se;
if (c)
{
*se = c;
s++;
}
}
}
//******************************************************************************
//
// MenuBufPrintLine() - Prints a string on the current line and
// advances to the next line. Newlines are not supported.
//
//******************************************************************************
void MenuBufPrintLine (const char *s)
{
int w, h;
USL_MeasureString (s, &w, &h, CurrentFont);
if (w > WindowW)
Error("MenuBufCPrintLine() - String exceeds width");
PrintX = WindowX;
DrawMenuBufPropString (PrintX, PrintY, s);
PrintY += h;
}
//******************************************************************************
//
// MenuBufPrint() - Prints a string in the current window. Newlines are
// supported.
//
//******************************************************************************
void MenuBufPrint (const char *string)
{
char c,
*se,
*s;
strcpy(strbuf, string);
s = strbuf;
while (*s)
{
se = s;
while ((c = *se) && (c != '\n'))
se++;
*se = '\0';
MenuBufPrintLine(s);
s = se;
if (c)
{
*se = c;
s++;
}
}
}
//******************************************************************************
//
// MenuTBufPrintLine() - Prints a string on the current line and
// advances to the next line. Newlines are not supported.
//
//******************************************************************************
void MenuTBufPrintLine (const char *s, int shade)
{
int w, h;
USL_MeasureString (s, &w, &h, CurrentFont);
if (w > WindowW)
Error("MenuBufCPrintLine() - String exceeds width");
PrintX = WindowX;
StringShade=shade;
DrawTMenuBufPropString (PrintX, PrintY, s);
PrintY += h;
}
//******************************************************************************
//
// FlipMenuBuf
//
//******************************************************************************
void FlipMenuBuf ( void )
{
int i;
int dh;
int h;
int y;
int dy;
int time;
int flip;
if (MenuBufStarted==false)
Error("Called FlipMenuBuf without menubuf started\n");
if (!readytoflip)
Error("FlipMenuBuf called without SetAlternateMenuBuf beforehand");
readytoflip=0;
if (Menuflipspeed<=5)
{
menubuf=menubuffers[alternatemenubuf];
strcpy(titlestring,menutitles[alternatemenubuf]);
RefreshMenuBuf(0);
}
else
{
menubuf=menubuffers[alternatemenubuf^1];
strcpy(titlestring,menutitles[alternatemenubuf^1]);
time=Menuflipspeed-5;
dh=(1024<<8)/time;
h=0;
dy=((MENUTITLEY*6)<<8)/time;
y=0;
flip=0;
titleyoffset=0;
for (i=0;i<time;i+=tics)
{
PositionMenuBuf(h>>8,NORMALVIEW,true);
h+=dh*tics;
y+=dy*tics;
titleyoffset=y>>8;
if ((h>=512<<8) && (flip==0))
{
MN_PlayMenuSnd (SD_MENUFLIP);
h=1536<<8;
dy=-dy;
menubuf=menubuffers[alternatemenubuf];
strcpy(titlestring,menutitles[alternatemenubuf]);
flip=1;
}
}
}
titleyoffset=0;
BackgroundDrawn=false;
}
//******************************************************************************
//
// RotatePlane
//
//******************************************************************************
void RotatePlane ( void )
{
SetupMenuBuf();
while (!(Keyboard[0x01]))
{
RefreshMenuBuf(100);
SetAlternateMenuBuf();
ClearMenuBuf();
DrawMenuBufPic (0,0,W_GetNumForName("newg11"));
DrawMenuBufItem (0,0,W_GetNumForName("apogee"));
FlipMenuBuf();
EraseMenuBufRegion(30,30,30,30);
RefreshMenuBuf(100);
SetAlternateMenuBuf();
ClearMenuBuf();
FlipMenuBuf();
}
ShutdownMenuBuf();
}