avp/3dc/win95/db.c
Rebellion Developments 218ca90543 Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from:
https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code

All text files were converted to Unix format.
2019-08-19 05:45:17 +02:00

1039 lines
24 KiB
C

#ifndef NDEBUG
/* ******************************************************************** *
* *
* DB.C - Debugging functions. *
* *
* By: Garry Lancaster Version: 2.0 *
* *
* ******************************************************************** */
/* N O T E S ********************************************************** */
/* A lot of these functions should be called via macros defined in db.h */
/* If you don't want to link this file with Windows OS files set the
* define DB_NOWINDOWS. This will also stop linking with the Direct Draw
* stuff, which is, after all, a part of Windows. If you want Windows
* stuff, but NOT Direct Draw, define DB_NODIRECTDRAW.
*/
/* ******************************************************************** *
* *
* I N T E R F A C E - both internal and external. *
* *
* ******************************************************************** */
/* I N C L U D E S **************************************************** */
/* Windows includes. Actually internal, but here to allow pre-compilation. */
#include "advwin32.h"
#ifndef DB_NOWINDOWS
#include <windows.h>
#include "advwin32.h"
#endif
#ifndef DB_NODIRECTDRAW
#include <ddraw.h>
#endif
#include "db.h" /* Contains most off the interface. */
/* G L O B A L S ****************************************************** */
/* Have external linkage. */
volatile BOOL DZ_NULL;
/* This variable dictates whether macros ending _opt get executed. */
int db_option = 0; /* Default is off. */
/* ******************************************************************** *
* *
* I N T E R N A L *
* *
* ******************************************************************** */
/* I N C L U D E S **************************************************** */
/* Defining DB_NOWINDOWS implies DB_NODIRECTDRAW should also be defined. */
#ifdef DB_NOWINDOWS
#ifndef DB_NODIRECTDRAW
#define DB_NODIRECTDRAW
#endif
#endif
/* ANSI includes. */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include <direct.h> /* For getcwd() */
#include <stdarg.h> /* For variable arguments. */
/* C O N S T A N T S ************************************************** */
/* Possible return value for MessageBox() */
#define NO_MEMORY 0
/* Possible value for the width field of a font_struct. */
#define PROP_WIDTH 0
/* Logfile name */
#define LOGFILE_NAME "LOGFILE.TXT"
/* Set this to 1 if the logfile name is an absolute path. Otherwise the
* logfile will go in the directory that is current when db_log_init()
* is called.
*/
#define ABSOLUTE_PATH 0
/* M A C R O S ******************************************************** */
/* Causes a division by zero exception. */
#define DB_FORCE_EXCEPTION() ( db_vol_zero = 1 / db_vol_zero )
/* Cause a brakepoint. */
#define DB_FORCE_BRAKEPOINT() do {__asm int 3} while(0)
/* T Y P E S ********************************************************** */
typedef struct font_struct *fontPtr;
struct font_struct {
void *dummy1;
unsigned short dummy2, dummy3;
void *dummy4;
char filename[16];
unsigned short width, height;
unsigned short ascent, avgwidth;
unsigned char byte_width;
unsigned char filler1;
short filler2;
char facename[28];
unsigned short *prop_width_dataP;
unsigned char *bitmapP;
};
union PtrPackTag
{
unsigned char *cP;
unsigned short *wP;
unsigned long *lP;
};
/* G L O B A L ******************************************************** */
/* Should all be static. */
static BOOL db_use_brakepoints = FALSE;
/* Name of file to output log messages to. */
static char LogFileNameP[255];
/* Have we initialized the log file? */
static int InitialisedLog = 0;
/* Type of display mode we are in. */
static int db_display_type = DB_DOS;
/* For DirectDraw mode. */
static struct db_dd_mode_tag dd_mode = {NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0};
static fontPtr FontP = NULL;
/* Volatile zero. */
static volatile int db_vol_zero = 0;
/* Text strings for output. */
static const char* db_assert_textA[ 3 ] =
{
"ASSERTION FAILED!",
"Expression: %s",
"File: %s Line: %d"
};
static const char* db_prompt_std =
"Quit program/force e(x)ception? [y/n/x]";
static const char* db_prompt_windows =
"Quit program? [Yes/No]/force exception? [Cancel]";
static const char* db_assert_log_begin_text =
"DB: FAILED ASSERTION BEGINS";
static const char* db_assert_log_end_text =
"DB: FAILED ASSERTION ENDS";
static const char* db_msg_log_begin_text =
"DB: MSG BEGINS";
static const char* db_msg_log_end_text =
"DB: MSG ENDS";
#ifdef DB_NOWINDOWS
static char db_log_file_name[261] = LOGFILE_NAME;
#else
static char db_log_file_name[MAX_PATH+1] = LOGFILE_NAME;
#endif
/* P R O T O S ******************************************************** */
/* Should all be static. */
static void db_do_std_prompt(unsigned yOffset);
#ifndef DB_NOWINDOWS
static void db_do_win_prompt(const char* titleStrP, const char* bodyStrP);
#endif /* ifndef DB_NOWINDOWS */
#ifndef DB_NODIRECTDRAW
/* Load debugging font, return NULL if we fail. */
static fontPtr guiload_font(char *new_fname);
/* Cleanup function for the above. */
static fontPtr CleanupFontLoadFail(HANDLE fH, fontPtr fontP);
/* Outputs debugging text. */
static void out_text(LPDIRECTDRAWSURFACE surfP, int xc, int yc,
const char *text, short x_limit, fontPtr fP);
/* Debounce all the keys the Direct Draw stuff uses. */
static void Debounce(void);
/* Wait for any outstanding flip operations to be completed, provided
* that the user specified DB_FLIP in the bltOrFlip field of the
* db_dd_mode_tag function. If they specified DB_BLIT this function returns
* immediately.
*/
static void DbWaitForHw(void);
/* Flips between the draw and visible surfaces. */
static void DbFlip(void);
/* Blits the contents of the draw surface to the visible surface. */
static void DbBlt(void);
#endif /* ifndef DB_NODIRECTDRAW */
/* F U N C T I O N S ************************************************** */
/* ******************************************************************** *
* *
* I N T E R F A C E - both internal and external. *
* *
* ******************************************************************** */
/* NEW FNS for formatted debug strings. */
void __cdecl db_logf_fired(const char *fmtStrP, ...)
{
char msg[ 1024 ];
va_list varArgList;
va_start( varArgList, fmtStrP );
vsprintf( msg, fmtStrP, varArgList );
va_end( varArgList );
db_log_fired( msg );
}
void __cdecl db_printf_fired(int x, int y, const char *fmtStrP, ...)
{
char msg[ 256 ];
va_list varArgList;
va_start( varArgList, fmtStrP );
vsprintf( msg, fmtStrP, varArgList );
va_end( varArgList );
db_print_fired( x, y, msg );
}
void __cdecl db_msgf_fired(const char *fmtStrP, ...)
{
char msg[ 256 ];
va_list varArgList;
va_start( varArgList, fmtStrP );
vsprintf( msg, fmtStrP, varArgList );
va_end( varArgList );
db_msg_fired( (const char *) msg );
}
/* Called whenever an assertion fails. */
void db_assert_fail(const char *exprP, const char *fileP, int line)
{
db_log_fired( db_assert_log_begin_text );
db_log_fired( db_assert_textA[ 0 ] );
db_logf_fired( db_assert_textA[ 1 ], exprP );
db_logf_fired( db_assert_textA[ 2 ], fileP, line );
db_log_fired( db_assert_log_end_text );
switch(db_display_type)
{
case DB_DOS:
printf( db_assert_textA[ 0 ] );
printf("\n");
printf( db_assert_textA[ 1 ], exprP );
printf("\n");
printf( db_assert_textA[ 2 ], fileP, line );
printf("\n");
db_do_std_prompt( 0 );
break;
#ifndef DB_NODIRECTDRAW
case DB_DIRECTDRAW:
{
char msg[256];
unsigned short xLimit = (unsigned short) dd_mode.width;
/* Wait for any hardware to finish flipping. */
DbWaitForHw();
out_text((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP,
0, 0, db_assert_textA[ 0 ], xLimit, FontP);
wsprintf(msg, db_assert_textA[ 1 ], exprP);
out_text((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP,
0, 16, msg, xLimit, FontP);
wsprintf(msg, db_assert_textA[ 2 ], fileP, line);
out_text((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP,
0, 32, msg, xLimit, FontP);
db_do_std_prompt( 48 );
}
break;
#endif
#ifndef DB_NOWINDOWS
case DB_WINDOWS:
{
char fmtMsg[ 256 ];
char msg[256];
strcpy( fmtMsg, db_assert_textA[ 1 ] );
strcat( fmtMsg, db_assert_textA[ 2 ] );
strcat( fmtMsg, db_prompt_windows );
sprintf(msg, fmtMsg, exprP, fileP, line);
db_do_win_prompt( db_assert_textA[ 0 ], msg );
}
break;
#endif
default:
break;
}
}
/* Displays a message and has the program pause until the user responds
* to it.
*/
void db_msg_fired(const char *strP)
{
db_log_fired( db_msg_log_begin_text );
db_log_fired( strP );
db_log_fired( db_msg_log_end_text );
switch(db_display_type)
{
case DB_DOS:
printf("%s\n", strP);
db_do_std_prompt( 0 );
break;
#ifndef DB_NOWINDOWS
case DB_WINDOWS:
db_do_win_prompt( "Debugging Message", strP );
break;
#endif
#ifndef DB_NODIRECTDRAW
case DB_DIRECTDRAW:
{
unsigned short xLimit = (unsigned short) dd_mode.width;
/* Wait for any flip hardware to be ready. */
DbWaitForHw();
out_text((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP,
0, 0, strP, xLimit, FontP);
db_do_std_prompt( 16 );
}
break;
#endif
default:
break;
}
}
/* Displays a message and continues program execution immediately. */
void db_print_fired(int x, int y, const char *strP)
{
switch(db_display_type)
{
case DB_DOS:
printf("%s\n", strP);
break;
#ifndef DB_NOWINDOWS
case DB_WINDOWS:
break;
#endif
#ifndef DB_NODIRECTDRAW
case DB_DIRECTDRAW:
{
unsigned short xLimit = (unsigned short) (dd_mode.width - x);
out_text((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP, x, y,
strP, xLimit, FontP);
break;
}
#endif
default:
break;
}
}
/* Writes a message to a log file. */
/* At least files can be output in the same way under DOS, Windows and
* Direct Draw!
*/
void db_log_fired(const char *strP)
{
/* Have we intialised the file? */
if(!InitialisedLog) db_log_init();
{
/* Open a file for appending, creating one if it doesn't yet exist. */
FILE *fP = fopen(LogFileNameP, "a+");
if(!fP) return;
fprintf(fP, "%s\n", strP);
fclose(fP);
}
}
void db_log_init(void)
{
#if ABSOLUTE_PATH
sprintf( LogFileNameP, "%s", db_log_file_name );
#else
/* Append the log file name to the current working directory. */
sprintf( LogFileNameP, "%s\\%s", getcwd( LogFileNameP, 240 ),
db_log_file_name );
#endif
/* Delete old log file. */
remove(LogFileNameP);
/* Flag that we have initialised the log file. */
InitialisedLog = 1;
}
extern void db_set_log_file_ex(const char *strP)
{
InitialisedLog = 0;
strcpy(db_log_file_name, strP);
}
void db_set_mode_ex(int mode, void *modeInfoP, void *newFontP)
{
db_display_type = mode;
#ifndef DB_NODIRECTDRAW
if(dd_mode.visibleSurfaceP)
{
IDirectDrawSurface_Release((LPDIRECTDRAWSURFACE) dd_mode.visibleSurfaceP);
dd_mode.visibleSurfaceP = NULL;
}
if(dd_mode.drawSurfaceP)
{
IDirectDrawSurface_Release((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP);
dd_mode.drawSurfaceP = NULL;
}
if(mode == DB_DIRECTDRAW)
{
dd_mode = *((struct db_dd_mode_tag *) modeInfoP);
if(dd_mode.visibleSurfaceP)
{
IDirectDrawSurface_AddRef((LPDIRECTDRAWSURFACE) dd_mode.visibleSurfaceP);
}
if(dd_mode.drawSurfaceP)
{
IDirectDrawSurface_AddRef((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP);
}
if(!FontP)
{
if(!newFontP)
FontP = guiload_font("DIALOG.FNT");
else
FontP = (fontPtr) newFontP;
}
if(!FontP)
{
db_log_fired("DB ERROR: Font load failed. Exiting...");
exit(0);
}
}
#endif
}
/* Called to set whether exceptions or brakepoints are called. */
void DbUseBrakepoints(BOOL use_brakepoints)
{
db_use_brakepoints = use_brakepoints;
}
int db_get_mode(void** modeInfoPP, void **FontPP)
{
// blank return areas
*FontPP = NULL;
*modeInfoPP = NULL;
#ifndef DB_NODIRECTDRAW
if(db_display_type == DB_DIRECTDRAW)
{
// copy font data
*FontPP = (void *) FontP;
// copy surface data
*modeInfoPP = (void *) &dd_mode;
}
#endif
return db_display_type;
}
void db_uninit(void)
{
#ifndef DB_NODIRECTDRAW
if(FontP)
{
if(FontP->bitmapP)
{
GlobalFree(FontP->bitmapP);
}
if(FontP->prop_width_dataP)
{
GlobalFree(FontP->prop_width_dataP);
}
GlobalFree(FontP);
FontP = NULL;
}
if(dd_mode.visibleSurfaceP)
{
IDirectDrawSurface_Release((LPDIRECTDRAWSURFACE) dd_mode.visibleSurfaceP);
}
if(dd_mode.drawSurfaceP)
{
IDirectDrawSurface_Release((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP);
}
#endif
}
/* ******************************************************************** *
* *
* I N T E R N A L *
* *
* ******************************************************************** */
static void db_do_std_prompt(unsigned yOffset)
{
int ch = 0;
switch(db_display_type)
{
case DB_DOS:
printf( db_prompt_std );
printf("\n");
do
{
ch = toupper(getch());
}
while((ch != 'N') && (ch != 'Y') && (ch != 'X'));
break;
#ifndef DB_NODIRECTDRAW
case DB_DIRECTDRAW:
{
SHORT response;
BOOL done = FALSE;
unsigned short xLimit = (unsigned short) dd_mode.width;
out_text((LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP,
0, yOffset, db_prompt_std, xLimit, FontP);
/* Show the message. */
if(dd_mode.bltOrFlip == DB_FLIP)
{
DbFlip();
}
else
{
DbBlt();
}
/* Wait for a valid key press. */
do
{
response = GetAsyncKeyState('Y');
if(response & 0x8000)
{
ch = 'Y';
done = TRUE;
}
response = GetAsyncKeyState('N');
if(response & 0x8000)
{
ch = 'N';
done = TRUE;
}
response = GetAsyncKeyState('X');
if(response & 0x8000)
{
ch = 'X';
done = TRUE;
}
}
while(!done);
Debounce();
/* Return the flip surfaces to their pre-message state. */
if(dd_mode.bltOrFlip == DB_FLIP)
{
DbFlip();
}
break;
}
#endif /* ifndef DB_NODIRECTDRAW */
}/* switch(db_display_type) */
if(ch == 'Y')
{
exit(-10);
}
else if(ch == 'X')
{
if(db_use_brakepoints)
{
DB_FORCE_BRAKEPOINT();
}
else
{
DB_FORCE_EXCEPTION();
}
}
}/* db_do_std_prompt() */
#ifndef DB_NOWINDOWS
static void db_do_win_prompt(const char* titleStrP, const char* bodyStrP)
{
int response;
response = MessageBox
(
NULL, /* Dialog has no KNOWN parent window. */
bodyStrP, /* Message to go in box. */
titleStrP, /* Box title. */
MB_YESNOCANCEL| /* Put up a 'Yes' and a 'No' button. */
MB_SETFOREGROUND| /* Shove message box to front of display. */
MB_ICONEXCLAMATION| /* Use an exclamation mark to decorate box. */
MB_TASKMODAL /* Suspend current task until box is closed. */
);
if((response == IDYES) || (response == NO_MEMORY))
{
exit( -10 );
}
else if(response == IDCANCEL)
{
if(db_use_brakepoints)
{
DB_FORCE_BRAKEPOINT();
}
else
{
DB_FORCE_EXCEPTION();
}
}
}/* db_do_win_prompt() */
#endif /* ifndef DB_NOWINDOWS */
#ifndef DB_NODIRECTDRAW
static fontPtr guiload_font(char *new_fname)
{
HANDLE *fH;
BOOL status;
unsigned short c, byte, y;
union PtrPackTag dest;
unsigned char inByte;
fontPtr fntSP;
DWORD bytesRead;
/* Open file for reading */
fH = CreateFile(new_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(!fH)
{
db_log_fired("DB ERROR: Couldn't open font file.");
return CleanupFontLoadFail(NULL, NULL);
}
/* Allocate memory for our font structure */
fntSP = (fontPtr)
GlobalAlloc(GMEM_FIXED, sizeof(struct font_struct));
if(!fntSP)
{
db_log_fired("DB ERROR: Not enough memory for font structure.");
return CleanupFontLoadFail(fH, NULL);
}
/* Nullify pointers inside the font structure. */
fntSP->bitmapP = NULL;
fntSP->prop_width_dataP = NULL;
/* Load up font structure */
status = ReadFile(fH, fntSP, sizeof(struct font_struct), &bytesRead,
NULL);
if((!status) || (bytesRead != sizeof(struct font_struct)))
{
db_log_fired("DB ERROR: Error reading structure from font file.");
return CleanupFontLoadFail(fH, fntSP);
}
/* Allocate memory for font bitmap */
fntSP->bitmapP = (unsigned char *) GlobalAlloc(GMEM_FIXED,
fntSP->byte_width * dd_mode.bitsPerPixel * fntSP->height * 128);
if(!fntSP->bitmapP)
{
db_log_fired("DB ERROR: Not enough memory for font bitmap.");
return CleanupFontLoadFail(fH, fntSP);
}
/* Work out proportional text widths for this font
* (if the font is proportional).
*/
if(fntSP->width == PROP_WIDTH)
{
/* Allocate memory for proportional width data */
fntSP->prop_width_dataP = (unsigned short *)
GlobalAlloc(GMEM_FIXED, 256);
if(!fntSP->prop_width_dataP)
{
db_log_fired("DB ERROR: Not enough memory for proportional "
"font data");
return CleanupFontLoadFail(fH, fntSP);
}
/* Read proportional width data */
status = ReadFile(fH, fntSP->prop_width_dataP, 256, &bytesRead,
NULL);
if((!status) || (bytesRead != 256))
{
db_log_fired("DB ERROR: Error reading proportional font data "
"from file.");
return CleanupFontLoadFail(fH, fntSP);
}
/* Round width of font to nearest long word. */
{
int i;
unsigned short *propP = fntSP->prop_width_dataP;
if(dd_mode.bitsPerPixel == 8)
{
for(i = 0; i < 128; i ++)
{
/* Round up to 4 pixels. */
*propP = (unsigned short) ((*propP + 3U) & (~3U));
}
propP++;
}
else
{
for(i = 0; i < 128; i ++)
{
/* Round up to 2 pixels. */
*propP = (unsigned short) ((*propP + 1U) & (~1U));
}
propP++;
}
}
}
else
{
/* Round width to nearest long word. */
if(dd_mode.bitsPerPixel == 8)
{
/* Round up to 4 pixels. */
fntSP->width = (unsigned char) ((fntSP->width + 2) & (~3));
}
else
{
/* Round up to 2 pixels. */
fntSP->width = (unsigned char) ((fntSP->width + 1) & (~1));
}
}
/* Load up bitmap data */
dest.cP = fntSP->bitmapP;
for(c = 0; c < 128; c ++)
{
for(y = 0; y < fntSP->height; y ++)
{
for(byte = 0; byte < fntSP->byte_width; byte ++)
{
unsigned char bitMask = 0x80;
/* Read a byte of data */
status = ReadFile(fH, &inByte, 1, &bytesRead, NULL);
if((!status) || (bytesRead != 1))
{
db_log_fired("DB ERROR: Error reading font bitmap from "
"file.");
return CleanupFontLoadFail(fH, fntSP);
}
/* Translate 1 bit per pixel data into current Direct Draw
* screen mode bit depth.
*/
if(dd_mode.bitsPerPixel == 8)
{
do
{
if(inByte & bitMask) *(dest.cP) =
(unsigned char) dd_mode.foreCol;
else *(dest.cP) = (unsigned char) dd_mode.backCol;
dest.cP++;
/* Shift bitMask 1 bit to the right */
bitMask >>= 1;
}
while(bitMask);
}
else
{
do
{
if(inByte & bitMask) *(dest.wP) = dd_mode.foreCol;
else *(dest.wP) = dd_mode.backCol;
dest.wP++;
/* Shift bitMask 1 bit to the right */
bitMask >>= 1;
}
while(bitMask);
}
}
}
}
/* Close the font file */
CloseHandle(fH);
return fntSP;
}
static fontPtr CleanupFontLoadFail(HANDLE fH, fontPtr fontP)
{
/* Close file if necessary */
if(fH) CloseHandle(fH);
/* Is the font struct allocated? */
if(fontP)
{
/* Yes. Is the bitmap allocated? If so, free it. */
if(fontP->bitmapP) GlobalFree(fontP->bitmapP);
/* Is the proportional width data allocated. If so, free it. */
if(fontP->prop_width_dataP) GlobalFree(fontP->prop_width_dataP);
/* Free the font structure. */
GlobalFree(fontP);
}
return NULL;
}
static void out_text(LPDIRECTDRAWSURFACE surfP, int xc, int yc,
const char *text, short x_limit, fontPtr fP)
{
register unsigned long *srcP, *destP;
register unsigned int x, y;
unsigned long heightTimesPitch, charOffset;
unsigned int prop_width;
int srcIncr, longsPerLine;
unsigned int bitShift;
DDSURFACEDESC surfaceDesc;
/* Lock the surface. */
{
HRESULT res;
surfaceDesc.dwSize = sizeof surfaceDesc;
res = IDirectDrawSurface_Lock(surfP, NULL, &surfaceDesc,
DDLOCK_WAIT, NULL);
if(res != DD_OK)
{
db_log3("Couldn't lock surface.");
return;
}
}
/* Round xc to nearest long word. */
if(dd_mode.bitsPerPixel == 8)
{
xc = (xc + 2) & (~3);
bitShift = 2;
}
else
{
xc = (xc + 1) & (~1);
bitShift = 1;
}
/* Point to DRAM buffer co-ordinate where the top left of the
* first character should be written.
*/
destP = (unsigned long *) surfaceDesc.lpSurface +
((yc * surfaceDesc.lPitch) >> 2) + (xc >> bitShift);
heightTimesPitch = (fP->height * surfaceDesc.lPitch) >> 2;
longsPerLine = (fP->byte_width * dd_mode.bitsPerPixel) >> 2;
charOffset = longsPerLine * fP->height;
/* Write our text string */
while(*text != '\0')
{
/* Blit a single character */
/* Point srcP to first byte of the bitmap for the current
* character.
*/
srcP = ((unsigned long *) fP->bitmapP) + (*text) * charOffset;
/* Get width of this character (in pixels). */
if(fP->width == PROP_WIDTH)
prop_width = *(fP->prop_width_dataP + (*text));
else prop_width = fP->width;
/* Check we will not exceed our original x_limit if we blit
* this character. If we will, we should stop writing.
*/
x_limit = (short) (x_limit - prop_width);
if(x_limit < 0) break;
/* Convert prop_width from pixels to longs. */
prop_width >>= bitShift;
srcIncr = longsPerLine - prop_width;
y = fP->height;
do
{
x = prop_width;
do
{
/* Move 1 long word. */
*destP++ = *srcP++;
}
while(--x != 0);
/* Point to start of next horizontal line of character square
* in DRAM buffer.
*/
destP += (surfaceDesc.lPitch >> 2) - prop_width;
srcP += srcIncr;
}
while(--y != 0);
/* Point to start of next character position in DRAM buffer */
destP -= heightTimesPitch - prop_width;
/* Advance one character in text string */
text++;
}
/* Unlock surface. */
{
HRESULT res;
res = IDirectDrawSurface_Unlock(surfP,
(LPVOID) surfaceDesc.lpSurface);
if(res != DD_OK) db_log_fired("Couldn't unlock surface.");
}
return;
}
static void Debounce(void)
{
BOOL bouncing;
/* Debounce all the keys we use - that is Y, N, and RETURN. */
do
{
bouncing = FALSE;
if(GetAsyncKeyState('Y') & 0x8000) bouncing = TRUE;
if(GetAsyncKeyState('N') & 0x8000) bouncing = TRUE;
if(GetAsyncKeyState('X') & 0x8000) bouncing = TRUE;
if(GetAsyncKeyState(VK_RETURN) & 0x8000) bouncing = TRUE;
}
while(bouncing);
}
static void DbWaitForHw(void)
{
/* Wait until the last flip is finished and the last blt done */
BOOL finished;
/* Stay in this loop until the hardware is free. */
do
{
finished = TRUE;
/* Make sure all flips are done. */
if(dd_mode.bltOrFlip == DB_FLIP)
{
if(IDirectDrawSurface_GetFlipStatus(
(LPDIRECTDRAWSURFACE) dd_mode.visibleSurfaceP,
DDGFS_ISFLIPDONE) != DD_OK)
finished = FALSE;
}
}
while(!finished);
}
static void DbFlip(void)
{
LPDIRECTDRAWSURFACE fromSurfP =
(LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP;
LPDIRECTDRAWSURFACE toSurfP =
(LPDIRECTDRAWSURFACE) dd_mode.visibleSurfaceP;
HRESULT res;
/* Try to flip the screen. */
res = IDirectDrawSurface_Flip(toSurfP, fromSurfP, DDFLIP_WAIT);
if(res != DD_OK)
db_log_fired("Internal debug flip failed - message lost!");
}
static void DbBlt(void)
{
LPDIRECTDRAWSURFACE fromSurfP =
(LPDIRECTDRAWSURFACE) dd_mode.drawSurfaceP;
LPDIRECTDRAWSURFACE toSurfP =
(LPDIRECTDRAWSURFACE) dd_mode.visibleSurfaceP;
HRESULT res;
RECT toRect;
/* Initialise to Rect. */
toRect.left = dd_mode.bltXOffset;
toRect.top = dd_mode.bltYOffset;
toRect.right = toRect.left + dd_mode.width;
toRect.bottom = toRect.top + dd_mode.height;
/* Try to blit from the draw to the visible surface. */
res = IDirectDrawSurface_Blt(toSurfP, &toRect, fromSurfP, NULL,
DDBLT_WAIT, NULL);
if(res != DD_OK)
db_log_fired("Internal debug blit failed - message lost.");
}
#endif
#else
;
#endif /* ! NDEBUG */