mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
- Adding blinky text to the ENDOOM screen.
SVN r507 (trunk)
This commit is contained in:
parent
1f242fa79e
commit
97ad5a0d6b
3 changed files with 181 additions and 125 deletions
|
@ -1,3 +1,6 @@
|
|||
March 28, 2007
|
||||
- Adding blinky text to the ENDOOM screen.
|
||||
|
||||
March 24, 2007
|
||||
- Changed MakeKey's hash algorithm from a CRC32 to Paul Hsieh's SuperFastHash.
|
||||
|
||||
|
|
|
@ -261,128 +261,128 @@ static int ListActionCommands (const char *pattern)
|
|||
return count;
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative
|
||||
license. See:
|
||||
http://www.azillionmonkeys.com/qed/weblicense.html for license details.
|
||||
|
||||
http://www.azillionmonkeys.com/qed/hash.html */
|
||||
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
#define get16bits(d) (*((const WORD *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((DWORD)(((const BYTE *)(d))[1])) << 8)\
|
||||
+(DWORD)(((const BYTE *)(d))[0]) )
|
||||
#endif
|
||||
|
||||
DWORD SuperFastHash (const char *data, size_t len)
|
||||
{
|
||||
DWORD hash = 0, tmp;
|
||||
size_t rem;
|
||||
|
||||
if (len == 0 || data == NULL) return 0;
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--)
|
||||
{
|
||||
hash += get16bits (data);
|
||||
tmp = (get16bits (data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof (WORD);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem)
|
||||
{
|
||||
case 3: hash += get16bits (data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof (WORD)] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += get16bits (data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += *data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
/* ======================================================================== */
|
||||
|
||||
/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative
|
||||
license. See:
|
||||
http://www.azillionmonkeys.com/qed/weblicense.html for license details.
|
||||
|
||||
http://www.azillionmonkeys.com/qed/hash.html */
|
||||
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
#define get16bits(d) (*((const WORD *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((DWORD)(((const BYTE *)(d))[1])) << 8)\
|
||||
+(DWORD)(((const BYTE *)(d))[0]) )
|
||||
#endif
|
||||
|
||||
DWORD SuperFastHash (const char *data, size_t len)
|
||||
{
|
||||
DWORD hash = 0, tmp;
|
||||
size_t rem;
|
||||
|
||||
if (len == 0 || data == NULL) return 0;
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--)
|
||||
{
|
||||
hash += get16bits (data);
|
||||
tmp = (get16bits (data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof (WORD);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem)
|
||||
{
|
||||
case 3: hash += get16bits (data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof (WORD)] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += get16bits (data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += *data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* A modified version to do a case-insensitive hash */
|
||||
|
||||
#undef get16bits
|
||||
#define get16bits(d) ((((DWORD)tolower(((const BYTE *)(d))[1])) << 8)\
|
||||
+(DWORD)tolower(((const BYTE *)(d))[0]) )
|
||||
#define get16bits(d) ((((DWORD)tolower(((const BYTE *)(d))[1])) << 8)\
|
||||
+(DWORD)tolower(((const BYTE *)(d))[0]) )
|
||||
|
||||
DWORD SuperFastHashI (const char *data, size_t len)
|
||||
{
|
||||
DWORD hash = 0, tmp;
|
||||
size_t rem;
|
||||
|
||||
if (len <= 0 || data == NULL) return 0;
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--)
|
||||
{
|
||||
hash += get16bits (data);
|
||||
tmp = (get16bits (data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof (WORD);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem)
|
||||
{
|
||||
case 3: hash += get16bits (data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= tolower(data[sizeof (WORD)]) << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += get16bits (data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += tolower(*data);
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
DWORD SuperFastHashI (const char *data, size_t len)
|
||||
{
|
||||
DWORD hash = 0, tmp;
|
||||
size_t rem;
|
||||
|
||||
if (len <= 0 || data == NULL) return 0;
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--)
|
||||
{
|
||||
hash += get16bits (data);
|
||||
tmp = (get16bits (data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof (WORD);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem)
|
||||
{
|
||||
case 3: hash += get16bits (data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= tolower(data[sizeof (WORD)]) << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += get16bits (data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += tolower(*data);
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
unsigned int MakeKey (const char *s)
|
||||
{
|
||||
|
|
|
@ -104,6 +104,12 @@
|
|||
|
||||
#define TEXT_FONT_NAME "vga-rom-font.16"
|
||||
|
||||
// How many ms elapse between blinking text flips. On a standard VGA
|
||||
// adapter, the characters are on for 16 frames and then off for another 16.
|
||||
// The number here therefore corresponds roughly to the blink rate on a
|
||||
// 60 Hz display.
|
||||
#define BLINK_PERIOD 267
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class FBasicStartupScreen : public FStartupScreen
|
||||
|
@ -186,6 +192,7 @@ BYTE *ST_Util_LoadFont (const char *filename);
|
|||
void ST_Util_FreeFont (BYTE *font);
|
||||
BITMAPINFO *ST_Util_AllocTextBitmap (const BYTE *font);
|
||||
void ST_Util_DrawTextScreen (BITMAPINFO *bitmap_info, const BYTE *text_screen, const BYTE *font);
|
||||
void ST_Util_UpdateTextBlink (BITMAPINFO *bitmap_info, const BYTE *text_screen, const BYTE *font, bool blink_on);
|
||||
void ST_Util_DrawChar (BITMAPINFO *screen, const BYTE *font, int x, int y, BYTE charnum, BYTE attrib);
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
@ -1092,6 +1099,8 @@ void ST_Endoom()
|
|||
BYTE *font;
|
||||
MSG mess;
|
||||
BOOL bRet;
|
||||
bool blinking = false, blinkstate = false;
|
||||
int i;
|
||||
|
||||
if (endoom_lump < 0 || Wads.LumpLength (endoom_lump) != 4000)
|
||||
{
|
||||
|
@ -1125,7 +1134,6 @@ void ST_Endoom()
|
|||
// Draw the loading screen to a bitmap.
|
||||
StartupBitmap = ST_Util_AllocTextBitmap (font);
|
||||
ST_Util_DrawTextScreen (StartupBitmap, endoom_screen, font);
|
||||
ST_Util_FreeFont (font);
|
||||
|
||||
// Make the title banner go away.
|
||||
if (GameTitleWindow != NULL)
|
||||
|
@ -1138,20 +1146,38 @@ void ST_Endoom()
|
|||
LayoutMainWindow (Window, NULL);
|
||||
InvalidateRect (StartupScreen, NULL, TRUE);
|
||||
|
||||
// Wait until any key has been pressed or a quit message has been received
|
||||
|
||||
while ((bRet = GetMessage(&mess, NULL, 0, 0)) != 0)
|
||||
// Does this screen need blinking?
|
||||
for (i = 0; i < 80*25; ++i)
|
||||
{
|
||||
if (bRet == 0) // Received WM_QUIT
|
||||
if (endoom_screen[1+i*2] & 0x80)
|
||||
{
|
||||
exit (int(mess.wParam));
|
||||
blinking = true;
|
||||
break;
|
||||
}
|
||||
else if (bRet != -1)
|
||||
}
|
||||
if (blinking && SetTimer (Window, 0x5A15A, BLINK_PERIOD, NULL) == 0)
|
||||
{
|
||||
blinking = false;
|
||||
}
|
||||
|
||||
// Wait until any key has been pressed or a quit message has been received
|
||||
for (;;)
|
||||
{
|
||||
bRet = GetMessage (&mess, NULL, 0, 0);
|
||||
if (bRet == 0 || bRet == -1 || // bRet == 0 means we received WM_QUIT
|
||||
mess.message == WM_KEYDOWN || mess.message == WM_SYSKEYDOWN || mess.message == WM_LBUTTONDOWN)
|
||||
{
|
||||
if (mess.message == WM_KEYDOWN || mess.message == WM_SYSKEYDOWN || mess.message == WM_LBUTTONDOWN)
|
||||
if (blinking)
|
||||
{
|
||||
exit (0);
|
||||
KillTimer (Window, 0x5A15A);
|
||||
}
|
||||
ST_Util_FreeFont (font);
|
||||
exit (int(bRet == 0 ? mess.wParam : 0));
|
||||
}
|
||||
else if (blinking && mess.message == WM_TIMER && mess.hwnd == Window && mess.wParam == 0x5A15A)
|
||||
{
|
||||
ST_Util_UpdateTextBlink (StartupBitmap, endoom_screen, font, blinkstate);
|
||||
blinkstate = !blinkstate;
|
||||
}
|
||||
TranslateMessage (&mess);
|
||||
DispatchMessage (&mess);
|
||||
|
@ -1550,11 +1576,11 @@ void ST_Util_DrawTextScreen (BITMAPINFO *bitmap_info, const BYTE *text_screen, c
|
|||
|
||||
void ST_Util_DrawChar (BITMAPINFO *screen, const BYTE *font, int x, int y, BYTE charnum, BYTE attrib)
|
||||
{
|
||||
const BYTE bg_left = attrib & 0xF0;
|
||||
const BYTE bg_left = attrib & 0x70;
|
||||
const BYTE fg = attrib & 0x0F;
|
||||
const BYTE fg_left = fg << 4;
|
||||
const BYTE bg = bg_left >> 4;
|
||||
const BYTE color_array[4] = { bg_left | bg, attrib, fg_left | bg, fg_left | fg };
|
||||
const BYTE color_array[4] = { bg_left | bg, attrib & 0x7F, fg_left | bg, fg_left | fg };
|
||||
const BYTE *src = font + 1 + charnum * font[0];
|
||||
int pitch = screen->bmiHeader.biWidth >> 1;
|
||||
BYTE *dest = ST_Util_BitsForBitmap(screen) + x*4 + y * font[0] * pitch;
|
||||
|
@ -1574,3 +1600,30 @@ void ST_Util_DrawChar (BITMAPINFO *screen, const BYTE *font, int x, int y, BYTE
|
|||
dest += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_Util_UpdateTextBlink
|
||||
//
|
||||
// Draws the parts of the text screen that blink to the bitmap. The bitmap
|
||||
// must be the proper size for the font.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_Util_UpdateTextBlink (BITMAPINFO *bitmap_info, const BYTE *text_screen, const BYTE *font, bool on)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < 25; ++y)
|
||||
{
|
||||
for (x = 0; x < 80; ++x)
|
||||
{
|
||||
if (text_screen[1] & 0x80)
|
||||
{
|
||||
ST_Util_DrawChar (bitmap_info, font, x, y, on ? text_screen[0] : ' ', text_screen[1]);
|
||||
ST_Util_InvalidateRect (Window, bitmap_info, x*8, y*font[0], x*8+8, y*font[0]+font[0]);
|
||||
}
|
||||
text_screen += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue