rott/rott/rt_str.c

2054 lines
43 KiB
C
Executable File
Raw Permalink Blame History

/*
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_STR.C
// Contains the menu stuff!
//
//******************************************************************************
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include "rt_def.h"
#include "rt_menu.h"
#include "rt_util.h"
#include "rt_vid.h"
#include "rt_build.h"
#include "lumpy.h"
#include "rt_str.h"
#include "_rt_str.h"
#include "isr.h"
#include "rt_in.h"
#include "rt_menu.h"
#include "rt_view.h"
#include "w_wad.h"
#include "z_zone.h"
#include "modexlib.h"
#include "rt_main.h"
#include "rt_msg.h"
#include "rt_playr.h"
#include "rt_sound.h"
#include "myprint.h"
//MED
#include "memcheck.h"
//******************************************************************************
//
// GLOBALS
//
//******************************************************************************
int fontcolor;
//******************************************************************************
//
// LOCALS
//
//******************************************************************************
static int BKw;
static int BKh;
static char strbuf[MaxString];
//******************************************************************************
//
// VW_DrawClippedString ()
//
// Draws a string at x, y to bufferofs
//
//******************************************************************************
void VW_DrawClippedString (int x, int y, const char *string)
{
int width,height,ht;
byte *source;
int ch;
int oy;
ht = CurrentFont->height;
oy=y;
while ((ch = (unsigned char)*string++)!=0)
{
ch -= 31;
width = CurrentFont->width[ch];
source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
while (width--)
{
if ((x>=0) && (x<iGLOBAL_SCREENWIDTH))
{
y=oy;
VGAWRITEMAP(x&3);
height = ht;
while (height--)
{
if ((y>=0) && (y<iGLOBAL_SCREENHEIGHT))
{
if (*source>0)
#ifdef DOS
*((byte *)(bufferofs+ylookup[y]+(x>>2))) = *source;
#else
*((byte *)(bufferofs+ylookup[y]+x)) = *source;
#endif
}
source++;
y++;
}
}
x++;
}
}
}
//******************************************************************************
//
// US_ClippedPrint() - Prints a string in bufferofs. Newlines are supported.
//
//******************************************************************************
void US_ClippedPrint (int x, int y, const char *string)
{
char c,
*se;
char *s;
int startx;
strcpy(strbuf, string);
s = strbuf;
startx=x;
while (*s)
{
se = s;
while ((c = *se) && (c != '\n'))
se++;
*se = '\0';
VW_DrawClippedString ( x, y, s);
s = se;
if (c)
{
*se = c;
s++;
y += CurrentFont->height;
}
}
}
//******************************************************************************
//
// VW_DrawPropString ()
//
// Draws a string at px, py to bufferofs
//
//******************************************************************************
void VW_DrawPropString (const char *string)
{
#ifdef DOS
byte pix;
int width,step,height,ht;
byte *source, *dest, *origdest;
int ch,mask;
ht = CurrentFont->height;
dest = origdest = (byte *)(bufferofs+ylookup[py]+(px>>2));
mask = 1<<(px&3);
while ((ch = *string++)!=0)
{
ch -= 31;
width = step = CurrentFont->width[ch];
source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
while (width--)
{
VGAMAPMASK(mask);
height = ht;
while (height--)
{
pix = *source;
if (pix)
*dest = pix;
source++;
dest += linewidth;
}
px++;
mask <<= 1;
if (mask == 16)
{
mask = 1;
origdest++;
}
dest = origdest;
}
}
bufferheight = ht;
bufferwidth = ((dest+1)-origdest)*4;
#else
byte pix;
int width,step,height,ht;
byte *source, *dest, *origdest;
int ch,mask;
ht = CurrentFont->height;
dest = origdest = (byte *)(bufferofs+ylookup[py]+px);
while ((ch = (unsigned char)*string++)!=0)
{
ch -= 31;
width = step = CurrentFont->width[ch];
source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
while (width--)
{
height = ht;
while (height--)
{
pix = *source;
if (pix)
*dest = pix;
source++;
dest += linewidth;
}
px++;
origdest++;
dest = origdest;
}
}
bufferheight = ht;
bufferwidth = ((dest+1)-origdest);
#endif
}
//******************************************************************************
//
// VWB_DrawPropString ()
//
// Calls VW_DrawPropString then updates the mark block.
//
//******************************************************************************
void VWB_DrawPropString (const char *string)
{
int x;
x = px;
VW_DrawPropString (string);
VW_MarkUpdateBlock (x, py, px-1, py+bufferheight-1);
}
//******************************************************************************
//
// VW_DrawIPropString ()
//
// Draws a string at px, py to bufferofs
//
//******************************************************************************
void VW_DrawIPropString (const char *string)
{
byte pix;
int width,step,height,ht;
byte *source, *dest, *origdest;
int ch,mask;
ht = CurrentFont->height;
#ifdef DOS
dest = origdest = (byte *)(bufferofs+ylookup[py]+(px>>2));
#else
dest = origdest = (byte *)(bufferofs+ylookup[py]+px);
#endif
mask = 1<<(px&3);
while ((ch = (unsigned char)*string++)!=0)
{
ch -= 31;
width = step = CurrentFont->width[ch];
source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
while (width--)
{
VGAMAPMASK(mask);
height = ht;
while (height--)
{
pix = *source;
if (pix)
*dest = pix;
source++;
dest += linewidth;
}
px++;
#ifdef DOS
mask <<= 1;
if (mask == 16)
{
mask = 1;
origdest++;
}
#else
origdest++;
#endif
dest = origdest;
}
}
bufferheight = ht;
#ifdef DOS
bufferwidth = ((dest+1)-origdest)*4;
#else
bufferwidth = ((dest+1)-origdest);
#endif
}
//******************************************************************************
//
// VWB_DrawIPropString ()
//
// Calls VW_DrawIPropString then updates the mark block.
//
//******************************************************************************
void VWB_DrawIPropString (const char *string)
{
int x;
x = px;
VW_DrawIPropString (string);
VW_MarkUpdateBlock (x, py, px-1, py+bufferheight-1);
}
//******************************************************************************
//
// VWL_MeasureString ()
//
//******************************************************************************
void VWL_MeasureString (const char *s, int *width, int *height, const font_t *font)
{
*height = font->height;
for (*width = 0; *s; s++)
*width += font->width[(*((byte *)s))-31]; // proportional width
}
//******************************************************************************
//
// VWL_MeasureIntensityString ()
//
//******************************************************************************
void VWL_MeasureIntensityString (const char *s, int *width, int *height, const cfont_t *font)
{
*height = font->height;
for (*width = 0; *s; s++)
*width += font->width[(*((byte *)s))-31]; // proportional width
}
//******************************************************************************
//
// VW_MeasureIntensityPropString ()
//
//******************************************************************************
void VW_MeasureIntensityPropString (const char *string, int *width, int *height)
{
VWL_MeasureIntensityString (string, width, height, IFont);
}
//******************************************************************************
//
// VW_MeasurePropString ()
//
//******************************************************************************
void VW_MeasurePropString (const char *string, int *width, int *height)
{
VWL_MeasureString (string, width, height, CurrentFont);
}
//******************************************************************************
//
// US_MeasureStr ()
//
//******************************************************************************
void US_MeasureStr (int *width, int *height, const char * s, ...)
{
char c,
*se,
*ss;
int w,h;
va_list strptr;
char buf[300];
*width = 0;
*height = 0;
memset (&buf[0], 0, sizeof (buf));
va_start (strptr, s);
vsprintf (&buf[0], s, strptr);
va_end (strptr);
ss = &buf[0];
while (*ss)
{
se = ss;
while ((c = *se) && (c != '\n'))
se++;
*se = '\0';
VWL_MeasureString (ss, &w, &h, CurrentFont);
*height += h;
if (w > *width)
*width = w;
ss = se;
if (c)
{
*se = c;
ss++;
}
}
}
//******************************************************************************
//
// US_SetPrintRoutines() - Sets the routines used to measure and print
// from within the User Mgr. Primarily provided to allow switching
// between masked and non-masked fonts
//
//******************************************************************************
void US_SetPrintRoutines (void (*measure)(const char *, int *, int *, font_t *),
void (*print)(const char *))
{
USL_MeasureString = measure;
USL_DrawString = print;
}
//******************************************************************************
//
// US_Print() - Prints a string in the current window. Newlines are
// supported.
//
//******************************************************************************
void US_Print (const char *string)
{
char c,
*se,
*s;
int w,h;
strcpy(strbuf, string);
s = strbuf;
while (*s)
{
se = s;
while ((c = *se) && (c != '\n'))
se++;
*se = '\0';
USL_MeasureString (s, &w, &h, CurrentFont);
px = PrintX;
py = PrintY;
USL_DrawString (s);
s = se;
if (c)
{
*se = c;
s++;
PrintX = WindowX;
PrintY += h;
}
else
PrintX += w;
}
}
//******************************************************************************
//
// US_BufPrint() - Prints a string in bufferofs. Newlines are supported.
//
//******************************************************************************
void US_BufPrint (const char *string)
{
char c,
*se,
*s;
int startx;
strcpy(strbuf, string);
s = strbuf;
startx=PrintX;
while (*s)
{
se = s;
while ((c = *se) && (c != '\n'))
se++;
*se = '\0';
px = PrintX;
py = PrintY;
USL_DrawString (s);
PrintY = py;
PrintX = px;
s = se;
if (c)
{
*se = c;
s++;
PrintY += CurrentFont->height;
PrintX = startx;
}
}
}
//******************************************************************************
//
// US_PrintUnsigned () - Prints an unsigned long int
//
//******************************************************************************
void US_PrintUnsigned (unsigned long int n)
{
char buffer[32];
US_Print (ultoa (n, buffer, 10));
}
//******************************************************************************
//
// US_PrintSigned() - Prints a signed long
//
//******************************************************************************
void US_PrintSigned (long int n)
{
char buffer[32];
US_Print (ltoa (n, buffer, 10));
}
//******************************************************************************
//
// USL_PrintInCenter() - Prints a string in the center of the given rect
//
//******************************************************************************
void USL_PrintInCenter (const char *s, Rect r)
{
int w,h,
rw,rh;
USL_MeasureString (s,&w,&h, CurrentFont);
rw = r.lr.x - r.ul.x;
rh = r.lr.y - r.ul.y;
px = r.ul.x + ((rw - w) / 2);
py = r.ul.y + ((rh - h) / 2);
USL_DrawString (s);
}
//******************************************************************************
//
// US_PrintCentered() - Prints a string centered in the current window.
//
//******************************************************************************
void US_PrintCentered (const char *s)
{
Rect r;
r.ul.x = WindowX;
r.ul.y = WindowY;
r.lr.x = r.ul.x + WindowW;
r.lr.y = r.ul.y + WindowH;
USL_PrintInCenter (s, r);
}
//******************************************************************************
//
// US_CPrintLine() - Prints a string centered on the current line and
// advances to the next line. Newlines are not supported.
//
//******************************************************************************
void US_CPrintLine (const char *s)
{
int w, h;
USL_MeasureString (s, &w, &h, CurrentFont);
if (w > WindowW)
Error("US_CPrintLine() - String exceeds width");
px = WindowX + ((WindowW - w) / 2);
py = PrintY;
USL_DrawString (s);
PrintY += h;
}
//******************************************************************************
//
// US_CPrint() - Prints a string in the current window. Newlines are
// supported.
//
//******************************************************************************
void US_CPrint (const char *string)
{
char c,
*se,
*s;
strcpy(strbuf, string);
s = strbuf;
while (*s)
{
se = s;
while ((c = *se) && (c != '\n'))
se++;
*se = '\0';
US_CPrintLine (s);
s = se;
if (c)
{
*se = c;
s++;
}
}
}
//
//
// Text Input routines
//
//
//
//******************************************************************************
//
// USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
//
//******************************************************************************
static void USL_XORICursor (int x, int y, const char *s, int cursor, int color)
{
static boolean status; // VGA doesn't XOR...
char buf[MaxString];
int w,h;
int oldx = px;
int oldy = py;
strcpy (buf,s);
buf[cursor] = '\0';
USL_MeasureString (buf, &w, &h, CurrentFont);
if (status^=1)
{
px = x + w;
py = y;
if (color)
USL_DrawString ("\x80");
else
DrawMenuBufPropString (px, py, "\x80");
}
else
{
if (color)
{
VWB_Bar (px, py, BKw, BKh, color);
USL_DrawString (s);
}
else
{
EraseMenuBufRegion (px, py, BKw, BKh);
// EraseMenuBufRegion (px, py+1, BKw, BKh-2);
DrawMenuBufPropString (px, py, s);
}
}
px = oldx;
py = oldy;
}
//******************************************************************************
//
// US_LineInput() - Gets a line of user input at (x,y), the string defaults
// to whatever is pointed at by def. Input is restricted to maxchars
// chars or maxwidth pixels wide. If the user hits escape (and escok is
// true), nothing is copied into buf, and false is returned. If the
// user hits return, the current string is copied into buf, and true is
// returned
//
///******************************************************************************
extern byte * IN_GetScanName (ScanCode scan);
boolean US_LineInput (int x, int y, char *buf, const char *def, boolean escok,
int maxchars, int maxwidth, int color)
{
boolean redraw,
cursorvis,
cursormoved,
done,
result;
char s[MaxString],
olds[MaxString];
int i,
cursor,
w,h,
len;
int lasttime;
int lastkey;
int cursorwidth;
cursorwidth = CurrentFont->width[80-31];
memset (s, 0, MaxString);
memset (olds, 0, MaxString);
IN_ClearKeyboardQueue ();
BKw = maxwidth;
BKh = CurrentFont->height;
if (def)
strcpy (s, def);
else
*s = '\0';
*olds = '\0';
cursor = strlen (s);
cursormoved = redraw = true;
cursorvis = done = false;
lasttime = GetTicCount();
lastkey = getASCII ();
while (!done)
{
// if (GameEscaped==true)
// PauseLoop ();
IN_PumpEvents();
if (cursorvis)
USL_XORICursor (x, y, s, cursor, color);
LastScan = IN_InputUpdateKeyboard ();
if (Keyboard[sc_LShift] || Keyboard[sc_RShift])
lastkey = ShiftNames[LastScan];
else
lastkey = ASCIINames[LastScan];
switch (LastScan)
{
case sc_LeftArrow:
if (cursor)
{
cursor--;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_LeftArrow] = 0;
break;
case sc_RightArrow:
if (s[cursor])
{
cursor++;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_RightArrow] = 0;
break;
case sc_Home:
if ( cursor )
{
cursor = 0;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
Keyboard[sc_Home] = 0;
lastkey = key_None;
break;
case sc_End:
if ( cursor != (int)strlen (s) )
{
cursor = strlen (s);
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_End] = 0;
break;
case sc_Return:
strcpy (buf,s);
done = true;
result = true;
lastkey = key_None;
MN_PlayMenuSnd (SD_SELECTSND);
break;
case sc_Escape:
if (escok)
{
done = true;
result = false;
MN_PlayMenuSnd (SD_ESCPRESSEDSND);
}
lastkey = key_None;
break;
case sc_BackSpace:
if (cursor)
{
strcpy (s + cursor - 1,s + cursor);
cursor--;
redraw = true;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_BackSpace] = 0;
IN_ClearKeyboardQueue ();
break;
case sc_Delete:
if (s[cursor])
{
strcpy (s + cursor,s + cursor + 1);
redraw = true;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_Delete] = 0;
IN_ClearKeyboardQueue ();
break;
case 0x4c: // Keypad 5
case sc_UpArrow:
case sc_DownArrow:
case sc_PgUp:
case sc_PgDn:
case sc_Insert:
lastkey = key_None;
break;
}
// if (GameEscaped==true)
// PauseLoop ();
if (lastkey)
{
len = strlen (s);
USL_MeasureString (s, &w, &h, CurrentFont);
if
(
isprint(lastkey)
&& (len < MaxString - 1)
&& ((!maxchars) || (len < maxchars))
&& ((!maxwidth) || ((w+2) < (maxwidth-cursorwidth-2)))
)
{
int ls;
int rs;
for (i = len + 1;i > cursor;i--)
s[i] = s[i - 1];
s[cursor++] = lastkey;
redraw = true;
ls = Keyboard[sc_LShift];
rs = Keyboard[sc_RShift];
memset ((void*)Keyboard, 0, 127*sizeof(int)); // Clear printable keys
Keyboard[sc_LShift] = ls;
Keyboard[sc_RShift] = rs;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
}
// if (GameEscaped==true)
// PauseLoop ();
if (redraw)
{
if (color)
VWB_Bar (x, y, BKw, BKh, color);
else
EraseMenuBufRegion (x, y, BKw, BKh);
strcpy (olds, s);
px = x;
py = y;
if (color)
USL_DrawString (s);
else
DrawMenuBufPropString (px, py, s);
px = x;
py = y;
redraw = false;
}
if (cursormoved)
{
cursorvis = false;
lasttime = GetTicCount() - VBLCOUNTER;
cursormoved = false;
}
if (GetTicCount() - lasttime > VBLCOUNTER / 2)
{
lasttime = GetTicCount();
cursorvis ^= true;
}
if (cursorvis)
USL_XORICursor (x, y, s, cursor, color);
// if (GameEscaped==true)
// PauseLoop ();
if (color)
VW_UpdateScreen ();
else
RefreshMenuBuf (0);
}
if (cursorvis)
USL_XORICursor (x, y, s, cursor, color);
if (!result)
{
px = x;
py = y;
if (color)
USL_DrawString (olds);
else
DrawMenuBufPropString (px, py, olds);
}
// if (GameEscaped==true)
// PauseLoop ();
if (color)
VW_UpdateScreen ();
else
RefreshMenuBuf (0);
IN_ClearKeyboardQueue ();
return (result);
}
//******************************************************************************
//
// US_lineinput() - Gets a line of user input at (x,y), the string defaults
// to whatever is pointed at by def. Input is restricted to maxchars
// chars or maxwidth pixels wide. If the user hits escape (and escok is
// true), nothing is copied into buf, and false is returned. If the
// user hits return, the current string is copied into buf, and true is
// returned - PASSWORD INPUT
//
///******************************************************************************
boolean US_lineinput (int x, int y, char *buf, const char *def, boolean escok,
int maxchars, int maxwidth, int color)
{
boolean redraw,
cursorvis,
cursormoved,
done,
result;
char s[MaxString],
xx[MaxString],
olds[MaxString];
int i,
cursor,
w,h,
len;
int lasttime;
int lastkey;
int cursorwidth;
cursorwidth = CurrentFont->width[80-31];
memset (s, 0, MaxString);
memset (xx, 0, MaxString);
memset (olds, 0, MaxString);
IN_ClearKeyboardQueue ();
BKw = maxwidth;
BKh = CurrentFont->height;
if (def)
strcpy (s, def);
else
*s = '\0';
*olds = '\0';
cursor = strlen (s);
cursormoved = redraw = true;
cursorvis = done = false;
lasttime = GetTicCount();
lastkey = getASCII ();
while (!done)
{
// if (GameEscaped == true)
// PauseLoop ();
IN_PumpEvents();
if (cursorvis)
USL_XORICursor (x, y, xx, cursor, color);
LastScan = IN_InputUpdateKeyboard ();
if (Keyboard[sc_LShift] || Keyboard[sc_RShift])
lastkey = ShiftNames[LastScan];
else
lastkey = ASCIINames[LastScan];
switch (LastScan)
{
case sc_LeftArrow:
if (cursor)
{
cursor--;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_LeftArrow] = 0;
break;
case sc_RightArrow:
if (s[cursor])
{
cursor++;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_RightArrow] = 0;
break;
case sc_Home:
if ( cursor != 0 )
{
cursor = 0;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
Keyboard[sc_Home] = 0;
lastkey = key_None;
break;
case sc_End:
if ( cursor != (int)strlen( s ) )
{
cursor = strlen (s);
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_End] = 0;
break;
case sc_Return:
strcpy (buf,s);
done = true;
result = true;
lastkey = key_None;
MN_PlayMenuSnd (SD_SELECTSND);
break;
case sc_Escape:
if (escok)
{
done = true;
result = false;
MN_PlayMenuSnd (SD_ESCPRESSEDSND);
}
lastkey = key_None;
break;
case sc_BackSpace:
if (cursor)
{
strcpy (s + cursor - 1,s + cursor);
strcpy (xx + cursor - 1,xx + cursor);
cursor--;
redraw = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
cursormoved = true;
}
lastkey = key_None;
Keyboard[sc_BackSpace] = 0;
IN_ClearKeyboardQueue ();
break;
case sc_Delete:
if (s[cursor])
{
strcpy (s + cursor,s + cursor + 1);
strcpy (xx + cursor,xx + cursor + 1);
redraw = true;
cursormoved = true;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
lastkey = key_None;
Keyboard[sc_Delete] = 0;
IN_ClearKeyboardQueue ();
break;
case 0x4c: // Keypad 5
case sc_UpArrow:
case sc_DownArrow:
case sc_PgUp:
case sc_PgDn:
case sc_Insert:
lastkey = key_None;
break;
}
// if (GameEscaped==true)
// PauseLoop ();
if (lastkey)
{
len = strlen (s);
USL_MeasureString (xx, &w, &h, CurrentFont);
if
(
isprint(lastkey)
&& (len < MaxString - 1)
&& ((!maxchars) || (len < maxchars))
&& ((!maxwidth) || ((w+2) < (maxwidth-cursorwidth-2)))
)
{
int ls;
int rs;
for (i = len + 1;i > cursor;i--)
s[i] = s[i - 1];
s[cursor] = lastkey;
xx[cursor++] = '*';
redraw = true;
ls = Keyboard[sc_LShift];
rs = Keyboard[sc_RShift];
memset ((void*)Keyboard, 0, 127*sizeof(int)); // Clear printable keys
Keyboard[sc_LShift] = ls;
Keyboard[sc_RShift] = rs;
MN_PlayMenuSnd (SD_MOVECURSORSND);
}
}
// if (GameEscaped==true)
// PauseLoop ();
if (redraw)
{
if (color)
VWB_Bar (x, y, BKw, BKh, color);
else
EraseMenuBufRegion (x, y, BKw, BKh);
strcpy (olds, s);
px = x;
py = y;
if (color)
USL_DrawString (xx);
else
DrawMenuBufPropString (px, py, xx);
px = x;
py = y;
redraw = false;
}
if (cursormoved)
{
cursorvis = false;
lasttime = GetTicCount() - VBLCOUNTER;
cursormoved = false;
}
if (GetTicCount() - lasttime > VBLCOUNTER / 2)
{
lasttime = GetTicCount();
cursorvis ^= true;
}
if (cursorvis)
USL_XORICursor (x, y, xx, cursor, color);
if (color)
VW_UpdateScreen ();
else
RefreshMenuBuf (0);
}
if (cursorvis)
USL_XORICursor (x, y, xx, cursor, color);
if (!result)
{
px = x;
py = y;
if (color)
USL_DrawString (xx);
else
DrawMenuBufPropString (px, py, xx);
}
// if (GameEscaped==true)
// PauseLoop ();
if (color)
VW_UpdateScreen ();
else
RefreshMenuBuf (0);
IN_ClearKeyboardQueue ();
return (result);
}
//******************************************************************************
//******************************************************************************
//
// WINDOWING ROUTINES
//
//******************************************************************************
//******************************************************************************
//******************************************************************************
//
// US_ClearWindow() - Clears the current window to white and homes the
// cursor
//
//******************************************************************************
void US_ClearWindow (void)
{
VWB_Bar (WindowX, WindowY, WindowW, WindowH, 13);
PrintX = WindowX;
PrintY = WindowY;
}
//******************************************************************************
//
// US_DrawWindow() - Draws a frame and sets the current window parms
//
//******************************************************************************
void US_DrawWindow (int x, int y, int w, int h)
{
int i,
sx,
sy,
sw,
sh;
byte * shape;
pic_t *Win1;
pic_t *Win2;
pic_t *Win3;
pic_t *Win4;
pic_t *Win5;
pic_t *Win6;
pic_t *Win7;
pic_t *Win8;
pic_t *Win9;
// Cache in windowing shapes
shape = W_CacheLumpNum (W_GetNumForName ("window1"), PU_CACHE, Cvt_pic_t, 1);
Win1 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window2"), PU_CACHE, Cvt_pic_t, 1);
Win2 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window3"), PU_CACHE, Cvt_pic_t, 1);
Win3 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window4"), PU_CACHE, Cvt_pic_t, 1);
Win4 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window5"), PU_CACHE, Cvt_pic_t, 1);
Win5 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window6"), PU_CACHE, Cvt_pic_t, 1);
Win6 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window7"), PU_CACHE, Cvt_pic_t, 1);
Win7 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window8"), PU_CACHE, Cvt_pic_t, 1);
Win8 = (pic_t *) shape;
shape = W_CacheLumpNum (W_GetNumForName ("window9"), PU_CACHE, Cvt_pic_t, 1);
Win9 = (pic_t *) shape;
WindowX = x * 8;
WindowY = y * 8;
WindowW = w * 8;
WindowH = h * 8;
PrintX = WindowX;
PrintY = WindowY;
sx = (x - 1) * 8;
sy = (y - 1) * 8;
sw = (w + 1) * 8;
sh = (h + 1) * 8;
US_ClearWindow ();
VWB_DrawPic (sx, sy, Win1);
VWB_DrawPic (sx, sy + sh, Win7);
for (i = sx + 8;i <= sx + sw - 8; i += 8)
{
VWB_DrawPic (i, sy, Win2);
VWB_DrawPic (i, sy + sh, Win8);
}
VWB_DrawPic (i, sy, Win3);
VWB_DrawPic (i, sy + sh, Win9);
for (i = sy + 8;i <= sy + sh - 8; i += 8)
{
VWB_DrawPic (sx, i, Win4);
VWB_DrawPic (sx + sw, i, Win6);
}
}
//******************************************************************************
//
// US_CenterWindow() - Generates a window of a given width & height in the
// middle of the screen
//
//******************************************************************************
void US_CenterWindow (int w, int h)
{
//HDG US_DrawWindow (((MaxX / 8) - w) / 2, ((MaxY / 8) - h) / 2, w, h);
US_DrawWindow (((iGLOBAL_SCREENWIDTH / 8) - w) / 2,((iGLOBAL_SCREENHEIGHT / 8) - h) / 2, w, h);
}
//==============================================================================
//
// Intensity Font stuff
//
// TEXT FORMATTING COMMANDS - (Use EGA colors ONLY!)
// -------------------------------------------------
// /<hex digit> - Change the following word to <hex digit> color
// ` - Highlights the following word with lighter color of fontcolor
// /N<hex digit> - Change the fontcolor to a certain color
//
//==============================================================================
//******************************************************************************
//
// GetIntensityColor ()
//
//******************************************************************************
byte GetIntensityColor (byte pix)
{
if ((fontcolor<0) || (fontcolor>255))
Error("Intensity Color out of range\n");
return ((byte) intensitytable[(pix<<8)+fontcolor]);
}
//******************************************************************************
//
// DrawIntensityChar ()
//
// Draws an intensity character at px, py
//
//******************************************************************************
void DrawIntensityChar ( char ch )
{
byte pix;
int px1,py1;
int width,w1;
int height,h1;
int ht;
byte *source,*src1;
byte *dest;
byte *origdest,*orgdst1;
int mask;
px1 = px;py1 = py;
ht = IFont->height;
origdest = ( byte * )( bufferofs + ylookup[ py ] + px );
dest = origdest;
ch -= 31;
width = IFont->width[ (unsigned char)ch ];
source = ( ( byte * )IFont ) + IFont->charofs[ (unsigned char)ch ];
mask = 1 << ( px & 3 );
if ((iGLOBAL_SCREENWIDTH <= 320)||(StretchScreen == true)){
while( width-- )
{
VGAMAPMASK( mask );
height = ht;
while( height-- )
{
pix = *source;
if ( pix != 0xFE )
{
*dest = GetIntensityColor( pix );
}
source++;
dest += linewidth;
}
px++;
origdest++;
dest = origdest;
}
}else{//strech letter in x any direction
w1 = width;
h1 = ht;
orgdst1 = origdest;
src1 = source;
while( width-- )
{
VGAMAPMASK( mask );
height = ht;
while( height-- )
{
pix = *source;
if ( pix != 0xFE )
{
*dest = GetIntensityColor( pix );
*(dest+iGLOBAL_SCREENWIDTH) = GetIntensityColor( pix );
*(dest+1) = GetIntensityColor( pix );
*(dest+1+iGLOBAL_SCREENWIDTH) = GetIntensityColor( pix );
}
source++;
dest += linewidth*2;
}
px++;px++;
origdest++;origdest++;
dest = origdest;
}
}
}
//******************************************************************************
//
// GetColor ()
//
//******************************************************************************
int GetColor (int num)
{
int returnval;
if ((num >= '0') && (num <= '9'))
returnval = egacolor[num - '0'];
else
if ((num >= 'A') && (num <= 'F'))
returnval = egacolor[((num - 'A') + 10)];
return (returnval);
}
//******************************************************************************
//
// DrawIString ()
//
//******************************************************************************
static int oldfontcolor = 0;
static boolean highlight = false;
void DrawIString (unsigned short int x, unsigned short int y, const char *string, int flags)
{
char ch;
char temp;
px = x;
py = y;
while ((ch = *string++) != 0)
{
if ( !PERMANENT_MSG( flags ) )
{
// Highlighting is done only for 1 word - if we get a "space"
// and highlight is on ...., reset variables.
//
if ((ch == ' ') && (highlight == true))
{
highlight = false;
fontcolor = oldfontcolor;
DrawIntensityChar (ch);
}
else
// '\\' is color change to a specific EGA color (ie. egacolor)
//
if (ch == '\\')
{
temp = *string++;
temp = toupper (temp);
// Force fontcolor to a specific color egacolor[ RED ];
if (temp == 'N')
{
temp = *string++;
fontcolor = GetColor (temp);
oldfontcolor = fontcolor;
}
//bna added
else if (temp == 'X')
{
temp = *string;
fontcolor = egacolor[ RED ];
oldfontcolor = fontcolor;
}
else if (temp == 'Y')
{
temp = *string;
fontcolor = egacolor[ YELLOW ];
oldfontcolor = fontcolor;
}
else if (temp == 'Z')
{
temp = *string;
fontcolor = egacolor[ GREEN ];
oldfontcolor = fontcolor;
}
//bna added end
// Restore fontcolor to a previous color
else if (temp == 'O')
{
fontcolor = oldfontcolor;
}
else
{
oldfontcolor = fontcolor; // save off old font color
highlight = true; // set highlight
fontcolor = GetColor (temp);
}
}
else
// '`' is highlight the current fontcolor
//
if (ch == '`')
{
oldfontcolor = fontcolor; // save off old font color
highlight = true; // set highlight
if (fontcolor < 8) // only highlight the
fontcolor = fontcolor-10; // lower colors
}
else
DrawIntensityChar (ch);
}
else
DrawIntensityChar (ch);
}
if (highlight == true)
{
highlight = false;
fontcolor = oldfontcolor;
}
}
//******************************************************************************
//
// DrawIntensityString ()
//
//******************************************************************************
void DrawIntensityString (unsigned short int x, unsigned short int y, const char *string, int color)
{
char ch;
px = x;
py = y;
fontcolor=color;
while ((ch = *string++) != 0)
{
DrawIntensityChar (ch);
}
}
static unsigned short disp_offset = 160 * 24;
void DrawRottText
(
int x,
int y,
int ch,
int foreground,
int background
)
{
char *vid;
vid = ( char * )( 0xb0000 );
vid += y * 160;
vid += x * 2;
if ( ch != NONE )
{
*vid = ch;
}
vid++;
*vid = ( ( background & 0x0f ) << 4 ) | ( foreground & 0x0f );
}
void TextBox
(
int x1,
int y1,
int x2,
int y2,
int ch,
int foreground,
int background
)
{
int x;
int y;
for( x = x1; x <= x2; x++ )
{
for( y = y1; y <= y2; y++ )
{
DrawRottText( x, y, ch, foreground, background );
}
}
}
void TextFrame
(
int x1,
int y1,
int x2,
int y2,
int type,
int foreground,
int background
)
{
int x;
int y;
if ( type == 0 )
{
for( x = x1 + 1; x < x2; x++ )
{
DrawRottText( x, y1, type, foreground, background );
DrawRottText( x, y2, type, foreground, background );
}
for( y = y1 + 1; y < y2; y++ )
{
DrawRottText( x1, y, type, foreground, background );
DrawRottText( x2, y, type, foreground, background );
}
}
if ( type == SINGLE_FRAME )
{
DrawRottText( x1, y1, '<EFBFBD>', foreground, background );
DrawRottText( x2, y1, '<EFBFBD>', foreground, background );
DrawRottText( x1, y2, '<EFBFBD>', foreground, background );
DrawRottText( x2, y2, '<EFBFBD>', foreground, background );
for( x = x1 + 1; x < x2; x++ )
{
DrawRottText( x, y1, '<EFBFBD>', foreground, background );
DrawRottText( x, y2, '<EFBFBD>', foreground, background );
}
for( y = y1 + 1; y < y2; y++ )
{
DrawRottText( x1, y, '<EFBFBD>', foreground, background );
DrawRottText( x2, y, '<EFBFBD>', foreground, background );
}
}
if ( type == DOUBLE_FRAME )
{
DrawRottText( x1, y1, '<EFBFBD>', foreground, background );
DrawRottText( x2, y1, '<EFBFBD>', foreground, background );
DrawRottText( x1, y2, '<EFBFBD>', foreground, background );
DrawRottText( x2, y2, '<EFBFBD>', foreground, background );
for( x = x1 + 1; x < x2; x++ )
{
DrawRottText( x, y1, '<EFBFBD>', foreground, background );
DrawRottText( x, y2, '<EFBFBD>', foreground, background );
}
for( y = y1 + 1; y < y2; y++ )
{
DrawRottText( x1, y, '<EFBFBD>', foreground, background );
DrawRottText( x2, y, '<EFBFBD>', foreground, background );
}
}
}
void mysetxy
(
int x,
int y
)
{
disp_offset = ( x * 2 ) + ( y * 160 );
}
void myputch
(
char ch
)
{
int j;
char *disp_start = (char *)( 0xb0000 );
if ( disp_offset >= 160 * 24 )
{
for ( j = 160; j < 160 * 24; j += 2 )
{
*( disp_start + j - 160 ) = *( disp_start + j );
}
disp_offset = 160 * 23;
for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
{
*( disp_start + j ) = ' ';
}
}
if ( ch >= 32 )
{
*( disp_start + disp_offset ) = ch;
disp_offset = disp_offset + 2;
}
if ( ch == '\r' )
{
disp_offset = disp_offset / 160;
disp_offset = disp_offset * 160;
}
if ( ch == '\n' )
{
disp_offset = disp_offset + 160;
if ( disp_offset < 160 * 24 )
{
for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
160 ); j += 2 )
{
*( disp_start + j ) = ' ';
}
}
}
}
int printstring
(
char *string
)
{
int count;
char *ptr;
ptr = string;
count = 0;
while ( *ptr )
{
myputch( *ptr );
count++;
ptr++;
}
return( count );
}
int printnum
(
int number
)
{
char string[ 100 ];
int count;
itoa( number, string, 10 );
count = printstring( string );
return( count );
}
int printunsigned
(
unsigned long number,
int radix
)
{
char string[ 100 ];
int count;
ultoa( number, string, radix );
count = printstring( string );
return( count );
}
int myprintf
(
char *fmt,
...
)
{
va_list argptr;
int count;
char *ptr;
if (MONOPRESENT==false)
{
Debug("%s", fmt);
return 0;
}
va_start( argptr, fmt );
ptr = fmt;
count = 0;
while( *ptr != 0 )
{
if ( *ptr == '%' )
{
ptr++;
switch( *ptr )
{
case 0 :
return( EOF );
break;
case 'l' :
count += printnum( va_arg( argptr, int ) );
ptr++;
break;
case 'd' :
count += printnum( va_arg( argptr, int ) );
break;
case 's' :
count += printstring( va_arg( argptr, char * ) );
break;
case 'u' :
count += printunsigned( va_arg( argptr, int ), 10 );
break;
case 'x' :
case 'X' :
count += printunsigned( va_arg( argptr, int ), 16 );
break;
}
ptr++;
}
else
{
myputch( *ptr );
count++;
ptr++;
}
}
va_end( argptr );
return( count );
}