- Fixed: Thing_ProjectileAimed did not set the missile's speed correctly.

- The net start pane is now given focus when it is created, so it can
  receive keyboard input.
- Added playback of the "WeaponPickup" sound when a Hexen net game starts.
- Separated the different startup screens into classes for better
  modularization (which I should have done in the first place). (Sorry,
  have not done it for Linux yet, so that won't compile as-is.)


SVN r496 (trunk)
This commit is contained in:
Randy Heit 2007-03-06 01:33:18 +00:00
parent 3f1a681451
commit 560d4f8140
12 changed files with 378 additions and 311 deletions

View file

@ -1,3 +1,13 @@
March 5, 2007
- Fixed: Thing_ProjectileAimed did not set the missile's speed correctly.
March 3, 2007
- The net start pane is now given focus when it is created, so it can
receive keyboard input.
- Added playback of the "WeaponPickup" sound when a Hexen net game starts.
- Separated the different startup screens into classes for better
modularization (which I should have done in the first place).
February 28, 2007
- Changed the net start pane to open underneath the existing window instead
of scrunching the startup screen up to make room for it.

View file

@ -2080,7 +2080,7 @@ void D_DoomMain (void)
S_Init ();
Printf ("ST_Init: Init startup screen.\n");
ST_Init (R_GuesstimateNumTextures() + 5);
StartScreen = FStartupScreen::CreateInstance (R_GuesstimateNumTextures() + 5);
Printf ("P_Init: Checking cmd-line parameters...\n");
flags = dmflags;
@ -2212,16 +2212,16 @@ void D_DoomMain (void)
// Build status bar line!
//
if (deathmatch)
ST_HereticStatus("DeathMatch...");
StartScreen->AppendStatusLine("DeathMatch...");
if (dmflags & DF_NO_MONSTERS)
ST_HereticStatus("No Monsters...");
StartScreen->AppendStatusLine("No Monsters...");
if (dmflags & DF_MONSTERS_RESPAWN)
ST_HereticStatus("Respawning...");
StartScreen->AppendStatusLine("Respawning...");
if (autostart)
{
FString temp;
temp.Format ("Warp to map %s, Skill %d ", startmap, gameskill + 1);
ST_HereticStatus (temp);
StartScreen->AppendStatusLine(temp);
}
// [RH] Now that all text strings are set up,
@ -2251,10 +2251,10 @@ void D_DoomMain (void)
}
FActorInfo::StaticGameSet ();
ST_Progress ();
StartScreen->Progress ();
Printf ("R_Init: Init %s refresh subsystem.\n", GameNames[gameinfo.gametype]);
ST_HereticMessage ("Loading graphics", 0x3f);
StartScreen->LoadingStatus ("Loading graphics", 0x3f);
R_Init ();
Printf ("DecalLibrary: Load decals.\n");
@ -2322,11 +2322,11 @@ void D_DoomMain (void)
M_Init ();
Printf ("P_Init: Init Playloop state.\n");
ST_HereticMessage ("Init game engine", 0x3f);
StartScreen->LoadingStatus ("Init game engine", 0x3f);
P_Init ();
Printf ("D_CheckNetGame: Checking network game status.\n");
ST_HereticMessage ("Checking network game status.", 0x3f);
StartScreen->LoadingStatus ("Checking network game status.", 0x3f);
D_CheckNetGame ();
// [RH] Lock any cvars that should be locked now that we're
@ -2350,7 +2350,8 @@ void D_DoomMain (void)
autostart = true;
}
ST_Done();
delete StartScreen;
StartScreen = NULL;
V_Init2();
files = Args.GatherFiles ("-playdemo", ".lmp", false);

View file

@ -1358,7 +1358,7 @@ bool DoArbitrate (void *userdata)
D_ReadUserInfoStrings (netbuffer[1], &stream, false);
ST_NetMessage ("Found %s (node %d, player %d)",
StartScreen->NetMessage ("Found %s (node %d, player %d)",
players[netbuffer[1]].userinfo.netname,
node, netbuffer[1]+1);
}
@ -1503,8 +1503,8 @@ void D_ArbitrateNetStart (void)
data.gotsetup[0] = 0x80;
}
ST_NetInit ("Exchanging game information", 1);
if (!ST_NetLoop (DoArbitrate, &data))
StartScreen->NetInit ("Exchanging game information", 1);
if (!StartScreen->NetLoop (DoArbitrate, &data))
{
exit (0);
}
@ -1522,7 +1522,7 @@ void D_ArbitrateNetStart (void)
fprintf (debugfile, "player %d is on node %d\n", i, nodeforplayer[i]);
}
}
ST_NetDone();
StartScreen->NetDone();
}
static void SendSetup (DWORD playersdetected[MAXNETNODES], BYTE gotsetup[MAXNETNODES], int len)

View file

@ -1643,7 +1643,7 @@ static void goOn (int position, bool keepFacing, bool secret, bool resetinv)
if (thiscluster && (thiscluster->flags & CLUSTER_HUB))
{
if ((level.flags & LEVEL_NOINTERMISSION) || (nextcluster == thiscluster))
NoWipe = 4;
NoWipe = 35;
D_DrawIcon = "TELEICON";
}

View file

@ -224,7 +224,7 @@ void PacketGet (void)
if (err == WSAECONNRESET)
{ // The remote node aborted unexpectedly, so pretend it sent an exit packet
ST_NetMessage ("The connection from %s was dropped.\n",
StartScreen->NetMessage ("The connection from %s was dropped.\n",
players[sendplayer[node]].userinfo.netname);
doomcom.data[0] = 0x80; // NCMD_EXIT
@ -401,7 +401,7 @@ static void SendConAck (int num_connected, int num_needed)
{
PreSend (&packet, 4, &sendaddress[node]);
}
ST_NetProgress (doomcom.numnodes);
StartScreen->NetProgress (doomcom.numnodes);
}
bool Host_CheckForConnects (void *userdata)
@ -426,7 +426,7 @@ bool Host_CheckForConnects (void *userdata)
if (node == -1)
{
const BYTE *s_addr_bytes = (const BYTE *)&from->sin_addr;
ST_NetMessage ("Got extra connect from %d.%d.%d.%d:%d",
StartScreen->NetMessage ("Got extra connect from %d.%d.%d.%d:%d",
s_addr_bytes[0], s_addr_bytes[1], s_addr_bytes[2], s_addr_bytes[3],
from->sin_port);
packet.Message = PRE_ALLFULL;
@ -439,7 +439,7 @@ bool Host_CheckForConnects (void *userdata)
{
node = doomcom.numnodes++;
sendaddress[node] = *from;
ST_NetMessage ("Got connect from node %d.", node);
StartScreen->NetMessage ("Got connect from node %d.", node);
}
// Let the new guest (and everyone else) know we got their message.
@ -451,7 +451,7 @@ bool Host_CheckForConnects (void *userdata)
node = FindNode (from);
if (node >= 0)
{
ST_NetMessage ("Got disconnect from node %d.", node);
StartScreen->NetMessage ("Got disconnect from node %d.", node);
doomcom.numnodes--;
while (node < doomcom.numnodes)
{
@ -590,20 +590,20 @@ void HostGame (int i)
atterm (SendAbort);
ST_NetInit ("Waiting for players", numplayers);
StartScreen->NetInit ("Waiting for players", numplayers);
// Wait for numplayers-1 different connections
if (!ST_NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers))
if (!StartScreen->NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers))
{
exit (0);
}
// Now inform everyone of all machines involved in the game
memset (gotack, 0, sizeof(gotack));
ST_NetMessage ("Sending all here.");
ST_NetInit ("Done waiting", 1);
StartScreen->NetMessage ("Sending all here.");
StartScreen->NetInit ("Done waiting", 1);
if (!ST_NetLoop (Host_SendAllHere, (void *)gotack))
if (!StartScreen->NetLoop (Host_SendAllHere, (void *)gotack))
{
exit (0);
}
@ -611,7 +611,7 @@ void HostGame (int i)
popterm ();
// Now go
ST_NetMessage ("Go");
StartScreen->NetMessage ("Go");
packet.Fake = PRE_FAKE;
packet.Message = PRE_GO;
for (node = 1; node < doomcom.numnodes; node++)
@ -624,7 +624,7 @@ void HostGame (int i)
}
}
ST_NetMessage ("Total players: %d", doomcom.numnodes);
StartScreen->NetMessage ("Total players: %d", doomcom.numnodes);
doomcom.id = DOOMCOM_ID;
doomcom.numplayers = doomcom.numnodes;
@ -657,9 +657,9 @@ bool Guest_ContactHost (void *userdata)
{
if (packet.Message == PRE_CONACK)
{
ST_NetMessage ("Total players: %d", packet.NumNodes);
ST_NetInit ("Waiting for other players", packet.NumNodes);
ST_NetProgress (packet.NumPresent);
StartScreen->NetMessage ("Total players: %d", packet.NumNodes);
StartScreen->NetInit ("Waiting for other players", packet.NumNodes);
StartScreen->NetProgress (packet.NumPresent);
return true;
}
else if (packet.Message == PRE_DISCONNECT)
@ -676,7 +676,7 @@ bool Guest_ContactHost (void *userdata)
}
// In case the progress bar could not be marqueed, bump it.
ST_NetProgress (0);
StartScreen->NetProgress (0);
return false;
}
@ -695,7 +695,7 @@ bool Guest_WaitForOthers (void *userdata)
switch (packet.Message)
{
case PRE_CONACK:
ST_NetProgress (packet.NumPresent);
StartScreen->NetProgress (packet.NumPresent);
break;
case PRE_ALLHERE:
@ -707,7 +707,7 @@ bool Guest_WaitForOthers (void *userdata)
doomcom.numnodes = packet.NumNodes + 2;
sendplayer[0] = packet.ConsoleNum; // My player number
doomcom.consoleplayer = packet.ConsoleNum;
ST_NetMessage ("Console player number: %d", doomcom.consoleplayer);
StartScreen->NetMessage ("Console player number: %d", doomcom.consoleplayer);
for (node = 0; node < packet.NumNodes; node++)
{
sendaddress[node+2].sin_addr.s_addr = packet.machines[node].address;
@ -721,14 +721,14 @@ bool Guest_WaitForOthers (void *userdata)
}
}
ST_NetMessage ("Received All Here, sending ACK.");
StartScreen->NetMessage ("Received All Here, sending ACK.");
packet.Fake = PRE_FAKE;
packet.Message = PRE_ALLHEREACK;
PreSend (&packet, 2, &sendaddress[1]);
break;
case PRE_GO:
ST_NetMessage ("Received \"Go.\"");
StartScreen->NetMessage ("Received \"Go.\"");
return true;
case PRE_DISCONNECT:
@ -757,22 +757,22 @@ void JoinGame (int i)
atterm (SendAbort);
// Let host know we are here
ST_NetInit ("Contacting host", 0);
StartScreen->NetInit ("Contacting host", 0);
if (!ST_NetLoop (Guest_ContactHost, NULL))
if (!StartScreen->NetLoop (Guest_ContactHost, NULL))
{
exit (0);
}
// Wait for everyone else to connect
if (!ST_NetLoop (Guest_WaitForOthers, 0))
if (!StartScreen->NetLoop (Guest_WaitForOthers, 0))
{
exit (0);
}
popterm ();
ST_NetMessage ("Total players: %d", doomcom.numnodes);
StartScreen->NetMessage ("Total players: %d", doomcom.numnodes);
doomcom.id = DOOMCOM_ID;
doomcom.numplayers = doomcom.numnodes;

View file

@ -328,7 +328,7 @@ nolead: mobj->angle = R_PointToAngle2 (mobj->x, mobj->y, targ->x, targ->y);
// Set the missile's speed to reflect the speed it was spawned at.
if (mobj->flags & MF_MISSILE)
{
mobj->Speed = fixed_t (sqrtf (float(speed*speed + vspeed*vspeed)));
mobj->Speed = fixed_t (sqrt (double(mobj->momx)*mobj->momx + double(mobj->momy)*mobj->momy + double(mobj->momz)*mobj->momz));
}
// Hugger missiles don't have any vertical velocity
if (mobj->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))

View file

@ -297,7 +297,7 @@ void FTextureManager::AddGroup(const char * startlump, const char * endlump, int
{
CreateTexture (firsttx, usetype);
}
ST_Progress();
StartScreen->Progress();
}
}
@ -353,7 +353,7 @@ void FTextureManager::AddHiresTextures ()
newtex->TopOffset = Scale(oldtex->TopOffset, newtex->ScaleY, 8);
ReplaceTexture(oldtexno, newtex, true);
}
ST_Progress();
StartScreen->Progress();
}
}
}
@ -479,7 +479,7 @@ void FTextureManager::AddPatches (int lumpnum)
{
CreateTexture (Wads.CheckNumForName (name, ns_patches), FTexture::TEX_WallPatch);
}
ST_Progress();
StartScreen->Progress();
}
delete file;
@ -729,10 +729,10 @@ DWORD R_BlendForColormap (DWORD map)
void R_InitData ()
{
FTexture::InitGrayMap();
ST_Progress();
StartScreen->Progress();
TexMan.AddGroup("S_START", "S_END", ns_sprites, FTexture::TEX_Sprite);
R_InitPatches (); // Initializes "special" textures that have no external references
ST_Progress();
StartScreen->Progress();
R_InitTextures ();
TexMan.AddGroup("F_START", "F_END", ns_flats, FTexture::TEX_Flat);
R_InitBuildTiles ();
@ -741,9 +741,9 @@ void R_InitData ()
TexMan.LoadHiresTex ();
TexMan.DefaultTexture = TexMan.CheckForTexture ("-NOFLAT-", FTexture::TEX_Override, 0);
V_InitFonts();
ST_Progress();
StartScreen->Progress();
R_InitColormaps ();
ST_Progress();
StartScreen->Progress();
}
//===========================================================================

View file

@ -34,14 +34,27 @@
** Actual implementation is system-specific.
*/
extern void ST_Init(int maxProgress);
extern void (*ST_Done)();
extern void (*ST_Progress)();
extern void (*ST_HereticMessage)(const char *message, int attributes);
extern void (*ST_HereticStatus)(const char *status);
extern void (*ST_NetInit)(const char *message, int numplayers);
extern void (*ST_NetProgress)(int count);
extern void (*ST_NetMessage)(const char *format, ...); // cover for printf()
extern void (*ST_NetDone)();
extern bool (*ST_NetLoop)(bool (*timer_callback)(void *), void *userdata);
class FStartupScreen
{
public:
static FStartupScreen *CreateInstance(int max_progress);
FStartupScreen(int max_progress);
virtual ~FStartupScreen();
virtual void Progress() = 0;
virtual void LoadingStatus(const char *message, int colors); // Used by Heretic only
virtual void AppendStatusLine(const char *status); // Used by Heretic only
virtual void NetInit(const char *message, int num_players) = 0;
virtual void NetProgress(int count) = 0;
virtual void NetMessage(const char *format, ...) = 0; // cover for printf
virtual void NetDone() = 0;
virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata) = 0;
protected:
int MaxPos, CurPos, NotchPos;
};
extern FStartupScreen *StartScreen;
extern void ST_Endoom();

View file

@ -138,7 +138,7 @@ static void AddTiles (void *tiles)
tiledata++;
size--;
}
ST_Progress();
StartScreen->Progress();
if ((picanm[pic] & 63) && (picanm[pic] & 192))
{

View file

@ -512,7 +512,7 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int p
tex->UseType = FTexture::TEX_Null;
}
TexMan.AddTexture (tex);
ST_Progress();
StartScreen->Progress();
}
}
}

View file

@ -653,9 +653,10 @@ void RestoreConView()
ShowWindow (GameTitleWindow, SW_SHOW);
I_ShutdownInput (); // Make sure the mouse pointer is available.
// Make sure the progress bar isn't visible.
if (ST_Done != NULL)
if (StartScreen != NULL)
{
ST_Done();
delete StartScreen;
StartScreen = NULL;
}
}
@ -678,7 +679,11 @@ void ShowErrorPane(const char *text)
}
SetWindowText (Window, "Fatal Error - " WINDOW_TITLE);
if (ST_NetDone != NULL) ST_NetDone(); // Ensure that the network pane is hidden.
if (StartScreen != NULL) // Ensure that the network pane is hidden.
{
delete StartScreen;
StartScreen = NULL;
}
ErrorIcon = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, 0, 0, 0, 0, Window, NULL, g_hInst, NULL);
if (ErrorIcon != NULL)
{

View file

@ -106,6 +106,66 @@
// TYPES -------------------------------------------------------------------
class FBasicStartupScreen : public FStartupScreen
{
public:
FBasicStartupScreen(int max_progress, bool show_bar);
~FBasicStartupScreen();
void Progress();
void NetInit(const char *message, int num_players);
void NetProgress(int count);
void NetMessage(const char *format, ...); // cover for printf
void NetDone();
bool NetLoop(bool (*timer_callback)(void *), void *userdata);
protected:
LRESULT NetMarqueeMode;
int NetMaxPos, NetCurPos;
};
class FGraphicalStartupScreen : public FBasicStartupScreen
{
public:
FGraphicalStartupScreen(int max_progress);
~FGraphicalStartupScreen();
};
class FHereticStartupScreen : public FGraphicalStartupScreen
{
public:
FHereticStartupScreen(int max_progress, HRESULT &hr);
void Progress();
void LoadingStatus(const char *message, int colors);
void AppendStatusLine(const char *status);
protected:
int ThermX, ThermY, ThermWidth, ThermHeight;
int HMsgY, SMsgX;
};
class FHexenStartupScreen : public FGraphicalStartupScreen
{
public:
FHexenStartupScreen(int max_progress, HRESULT &hr);
void Progress();
void NetProgress(int count);
void NetDone();
};
class FStrifeStartupScreen : public FGraphicalStartupScreen
{
public:
FStrifeStartupScreen(int max_progress, HRESULT &hr);
~FStrifeStartupScreen();
void Progress();
protected:
void DrawStuff(int old_laser, int new_laser);
BYTE *StartupPics[4+2+1];
};
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void RestoreConView();
@ -134,32 +194,6 @@ void ST_Util_DrawChar (BITMAPINFO *screen, const BYTE *font, int x, int y, BYTE
static INT_PTR CALLBACK NetStartPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
static void ST_Basic_Init ();
static void ST_Basic_Done ();
static void ST_Basic_Progress ();
static void ST_Basic_HereticMessage (const char *message, int attributes);
static void ST_Basic_HereticStatus (const char *status);
static void ST_Basic_NetInit (const char *message, int numplayers);
static void ST_Basic_NetProgress (int count);
static void ST_Basic_NetMessage (const char *format, ...);
static void ST_Basic_NetDone ();
static bool ST_Basic_NetLoop (bool (*timer_callback)(void *), void *userdata);
static void ST_Hexen_Init ();
static void ST_Hexen_Done ();
static void ST_Hexen_Progress ();
static void ST_Hexen_NetProgress (int count);
static void ST_Heretic_Init ();
static void ST_Heretic_Progress ();
static void ST_Heretic_Message (const char *message, int attributes);
static void ST_Heretic_Status (const char *status);
static void ST_Strife_Init ();
static void ST_Strife_Done ();
static void ST_Strife_Progress ();
static void ST_Strife_DrawStuff (int old_laser, int new_laser);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern HINSTANCE g_hInst;
@ -167,16 +201,7 @@ extern HWND Window, ConWindow, ProgressBar, NetStartPane, StartupScreen, GameTit
// PUBLIC DATA DEFINITIONS -------------------------------------------------
void (*ST_Done)();
void (*ST_Progress)();
void (*ST_HereticMessage)(const char *message, int attributes);
void (*ST_HereticStatus)(const char *status);
void (*ST_NetInit)(const char *message, int numplayers);
void (*ST_NetProgress)(int count);
void (*ST_NetMessage)(const char *format, ...);
void (*ST_NetDone)();
bool (*ST_NetLoop)(bool (*timer_callback)(void *), void *userdata);
FStartupScreen *StartScreen;
BITMAPINFO *StartupBitmap;
CUSTOM_CVAR(Int, showendoom, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -187,13 +212,6 @@ CUSTOM_CVAR(Int, showendoom, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static int MaxPos, CurPos, NotchPos;
static int NetMaxPos, NetCurPos;
static LRESULT NetMarqueeMode;
static int ThermX, ThermY, ThermWidth, ThermHeight;
static int HMsgY, SMsgX;
static BYTE *StrifeStartupPics[4+2+1];
static const char *StrifeStartupPicNames[4+2+1] =
{
"STRTPA1", "STRTPB1", "STRTPC1", "STRTPD1",
@ -281,75 +299,123 @@ static const BYTE NetNotchBits[] =
//==========================================================================
//
// ST_Init
// FStartupScreen :: CreateInstance
//
// Initializes the startup screen for the detected game.
// Sets the size of the progress bar and displays the startup screen.
//
//==========================================================================
void ST_Init(int maxProgress)
FStartupScreen *FStartupScreen::CreateInstance(int max_progress)
{
MaxPos = maxProgress;
CurPos = 0;
NotchPos = 0;
FStartupScreen *scr = NULL;
HRESULT hr;
if (gameinfo.gametype == GAME_Hexen)
{
ST_Hexen_Init ();
scr = new FHexenStartupScreen(max_progress, hr);
}
else if (gameinfo.gametype == GAME_Heretic)
{
ST_Heretic_Init ();
scr = new FHereticStartupScreen(max_progress, hr);
}
else if (gameinfo.gametype == GAME_Strife)
{
ST_Strife_Init ();
scr = new FStrifeStartupScreen(max_progress, hr);
}
else
if (scr != NULL && FAILED(hr))
{
ST_Basic_Init ();
delete scr;
scr = NULL;
}
if (scr == NULL)
{
scr = new FBasicStartupScreen(max_progress, true);
}
return scr;
}
//==========================================================================
//
// ST_Basic_Init
// FStartupScreen Constructor
//
//==========================================================================
FStartupScreen::FStartupScreen(int max_progress)
{
MaxPos = max_progress;
CurPos = 0;
NotchPos = 0;
}
//==========================================================================
//
// FStartupScreen Destructor
//
//==========================================================================
FStartupScreen::~FStartupScreen()
{
}
//==========================================================================
//
// FStartupScreen :: LoadingStatus
//
// Used by Heretic for the Loading Status "window."
//
//==========================================================================
void FStartupScreen::LoadingStatus(const char *message, int colors)
{
}
//==========================================================================
//
// FStartupScreen :: AppendStatusLine
//
// Used by Heretic for the "status line" at the bottom of the screen.
//
//==========================================================================
void FStartupScreen::AppendStatusLine(const char *status)
{
}
//==========================================================================
//
// FBasicStartupScreen Constructor
//
// Shows a progress bar at the bottom of the window.
//
//==========================================================================
static void ST_Basic_Init ()
FBasicStartupScreen::FBasicStartupScreen(int max_progress, bool show_bar)
: FStartupScreen(max_progress)
{
if (show_bar)
{
ProgressBar = CreateWindowEx(0, PROGRESS_CLASS,
NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
0, 0, 0, 0,
Window, 0, g_hInst, NULL);
SendMessage (ProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,MaxPos));
LayoutMainWindow (Window, NULL);
ST_Done = ST_Basic_Done;
ST_Progress = ST_Basic_Progress;
ST_HereticMessage = ST_Basic_HereticMessage;
ST_HereticStatus = ST_Basic_HereticStatus;
ST_NetInit = ST_Basic_NetInit;
ST_NetProgress = ST_Basic_NetProgress;
ST_NetMessage = ST_Basic_NetMessage;
ST_NetDone = ST_Basic_NetDone;
ST_NetLoop = ST_Basic_NetLoop;
}
NetMaxPos = 0;
NetCurPos = 0;
}
//==========================================================================
//
// ST_Basic_Done
// FBasicStartupScreen Destructor
//
// Called just before entering graphics mode to deconstruct the startup
// screen.
//
//==========================================================================
static void ST_Basic_Done()
FBasicStartupScreen::~FBasicStartupScreen()
{
if (ProgressBar != NULL)
{
@ -361,13 +427,13 @@ static void ST_Basic_Done()
//==========================================================================
//
// ST_Basic_Progress
// FBasicStartupScreen :: Progress
//
// Bumps the progress meter one notch.
//
//==========================================================================
static void ST_Basic_Progress()
void FBasicStartupScreen::Progress()
{
if (CurPos < MaxPos)
{
@ -378,31 +444,7 @@ static void ST_Basic_Progress()
//==========================================================================
//
// ST_Basic_HereticMessage
//
// Only used by the Heretic startup screen.
//
//==========================================================================
static void ST_Basic_HereticMessage (const char *, int)
{
}
//==========================================================================
//
// ST_Basic_HereticStatus
//
// Only used by the Heretic startup screen.
//
//==========================================================================
static void ST_Basic_HereticStatus (const char *)
{
}
//==========================================================================
//
// ST_Basic_NetInit
// FBasicStartupScreen :: NetInit
//
// Shows the network startup pane if it isn't visible. Sets the message in
// the pane to the one provided. If numplayers is 0, then the progress bar
@ -412,7 +454,7 @@ static void ST_Basic_HereticStatus (const char *)
//
//==========================================================================
static void ST_Basic_NetInit(const char *message, int numplayers)
void FBasicStartupScreen::NetInit(const char *message, int numplayers)
{
NetMaxPos = numplayers;
if (NetStartPane == NULL)
@ -430,6 +472,7 @@ static void ST_Basic_NetInit(const char *message, int numplayers)
winrect.right - winrect.left, winrect.bottom - winrect.top + LayoutNetStartPane (NetStartPane, 0),
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
LayoutMainWindow (Window, NULL);
SetFocus (NetStartPane);
}
if (NetStartPane != NULL)
{
@ -470,18 +513,18 @@ static void ST_Basic_NetInit(const char *message, int numplayers)
}
NetMaxPos = numplayers;
NetCurPos = 0;
ST_NetProgress(1); // You always know about yourself
NetProgress(1); // You always know about yourself
}
//==========================================================================
//
// ST_Basic_NetDone
// FBasicStartupScreen :: NetDone
//
// Removes the network startup pane.
//
//==========================================================================
static void ST_Basic_NetDone()
void FBasicStartupScreen::NetDone()
{
if (NetStartPane != NULL)
{
@ -493,15 +536,15 @@ static void ST_Basic_NetDone()
//==========================================================================
//
// ST_Basic_NetMessage
// FBasicStartupScreen :: NetMessage
//
// Call this between ST_NetInit() and ST_NetDone() instead of Printf() to
// Call this between NetInit() and NetDone() instead of Printf() to
// display messages, in case the progress meter is mixed in the same output
// stream as normal messages.
//
//==========================================================================
static void ST_Basic_NetMessage(const char *format, ...)
void FBasicStartupScreen::NetMessage(const char *format, ...)
{
FString str;
va_list argptr;
@ -514,14 +557,14 @@ static void ST_Basic_NetMessage(const char *format, ...)
//==========================================================================
//
// ST_Basic_NetProgress
// FBasicStartupScreen :: NetProgress
//
// Sets the network progress meter. If count is 0, it gets bumped by 1.
// Otherwise, it is set to count.
//
//==========================================================================
static void ST_Basic_NetProgress(int count)
void FBasicStartupScreen :: NetProgress(int count)
{
if (count == 0)
{
@ -552,7 +595,7 @@ static void ST_Basic_NetProgress(int count)
//==========================================================================
//
// ST_Basic_NetLoop
// FBasicStartupScreen :: NetLoop
//
// The timer_callback function is called at least two times per second
// and passed the userdata value. It should return true to stop the loop and
@ -564,7 +607,7 @@ static void ST_Basic_NetProgress(int count)
//
//==========================================================================
static bool ST_Basic_NetLoop(bool (*timer_callback)(void *), void *userdata)
bool FBasicStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata)
{
BOOL bRet;
MSG msg;
@ -613,7 +656,7 @@ static bool ST_Basic_NetLoop(bool (*timer_callback)(void *), void *userdata)
static INT_PTR CALLBACK NetStartPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED)
if (msg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
{
PostQuitMessage (0);
return TRUE;
@ -623,23 +666,58 @@ static INT_PTR CALLBACK NetStartPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LP
//==========================================================================
//
// ST_Hexen_Init
// FGraphicalStartupScreen Constructor
//
// This doesn't really do anything. The subclass is responsible for
// creating the resources that will be freed by this class's destructor.
//
//==========================================================================
FGraphicalStartupScreen::FGraphicalStartupScreen(int max_progress)
: FBasicStartupScreen(max_progress, false)
{
}
//==========================================================================
//
// FGraphicalStartupScreen Destructor
//
//==========================================================================
FGraphicalStartupScreen::~FGraphicalStartupScreen()
{
if (StartupScreen != NULL)
{
DestroyWindow (StartupScreen);
StartupScreen = NULL;
}
if (StartupBitmap != NULL)
{
ST_Util_FreeBitmap (StartupBitmap);
StartupBitmap = NULL;
}
}
//==========================================================================
//
// FHexenStartupScreen Constructor
//
// Shows the Hexen startup screen. If the screen doesn't appear to be
// valid, it falls back to ST_Basic_Init.
// valid, it sets hr for a failure.
//
// The startup graphic is a planar, 4-bit 640x480 graphic preceded by a
// 16 entry (48 byte) VGA palette.
//
//==========================================================================
static void ST_Hexen_Init ()
FHexenStartupScreen::FHexenStartupScreen(int max_progress, HRESULT &hr)
: FGraphicalStartupScreen(max_progress)
{
int startup_lump = Wads.CheckNumForName ("STARTUP");
hr = E_FAIL;
if (startup_lump < 0 || Wads.LumpLength (startup_lump) != 153648 || !ST_Util_CreateStartupWindow())
{
ST_Basic_Init ();
return;
}
@ -676,53 +754,20 @@ static void ST_Hexen_Init ()
LayoutMainWindow (Window, NULL);
InvalidateRect (StartupScreen, NULL, TRUE);
ST_Done = ST_Hexen_Done;
ST_Progress = ST_Hexen_Progress;
ST_HereticMessage = ST_Basic_HereticMessage;
ST_HereticStatus = ST_Basic_HereticStatus;
ST_NetInit = ST_Basic_NetInit;
ST_NetProgress = ST_Hexen_NetProgress;
ST_NetMessage = ST_Basic_NetMessage;
ST_NetDone = ST_Basic_NetDone;
ST_NetLoop = ST_Basic_NetLoop;
// Not that this screen will be around long enough for anyone to
// really hear the music, but start it anyway.
S_ChangeMusic ("orb", true, true);
hr = S_OK;
}
//==========================================================================
//
// ST_Hexen_Done
//
// Called just before entering graphics mode to deconstruct the startup
// screen.
//
//==========================================================================
static void ST_Hexen_Done()
{
if (StartupScreen != NULL)
{
DestroyWindow (StartupScreen);
StartupScreen = NULL;
}
if (StartupBitmap != NULL)
{
ST_Util_FreeBitmap (StartupBitmap);
StartupBitmap = NULL;
}
}
//==========================================================================
//
// ST_Hexen_Progress
// FHexenStartupScreen :: Progress
//
// Bumps the progress meter one notch.
//
//==========================================================================
static void ST_Hexen_Progress()
void FHexenStartupScreen::Progress()
{
int notch_pos, x, y;
@ -746,18 +791,18 @@ static void ST_Hexen_Progress()
//==========================================================================
//
// ST_Hexen_NetProgress
// FHexenStartupScreen :: NetProgress
//
// Draws the red net noches in addition to the normal progress bar.
//
//==========================================================================
static void ST_Hexen_NetProgress (int count)
void FHexenStartupScreen::NetProgress(int count)
{
int oldpos = NetCurPos;
int x, y;
ST_Basic_NetProgress (count);
FGraphicalStartupScreen::NetProgress (count);
if (NetMaxPos != 0 && NetCurPos > oldpos)
{
for (; oldpos < NetCurPos && oldpos < ST_MAX_NETNOTCHES; ++oldpos)
@ -773,25 +818,40 @@ static void ST_Hexen_NetProgress (int count)
//==========================================================================
//
// ST_Heretic_Init
// FHexenStartupScreen :: NetDone
//
// Aside from the standard processing, also plays a sound.
//
//==========================================================================
void FHexenStartupScreen::NetDone()
{
S_Sound (CHAN_BODY, "PickupWeapon", 1, ATTN_NORM);
FGraphicalStartupScreen::NetDone();
}
//==========================================================================
//
// FHereticStartupScreen Constructor
//
// Shows the Heretic startup screen. If the screen doesn't appear to be
// valid, it falls back to ST_Basic_Init.
// valid, it returns a failure code in hr.
//
// The loading screen is an 80x25 text screen with character data and
// attributes intermixed, which means it must be exactly 4000 bytes long.
//
//==========================================================================
static void ST_Heretic_Init ()
FHereticStartupScreen::FHereticStartupScreen(int max_progress, HRESULT &hr)
: FGraphicalStartupScreen(max_progress)
{
int loading_lump = Wads.CheckNumForName ("LOADING");
BYTE loading_screen[4000];
BYTE *font;
hr = E_FAIL;
if (loading_lump < 0 || Wads.LumpLength (loading_lump) != 4000 || !ST_Util_CreateStartupWindow())
{
ST_Basic_Init ();
return;
}
@ -799,7 +859,6 @@ static void ST_Heretic_Init ()
if (font == NULL)
{
DestroyWindow (StartupScreen);
ST_Basic_Init ();
return;
}
@ -826,27 +885,18 @@ static void ST_Heretic_Init ()
ST_Util_SizeWindowForBitmap (1);
LayoutMainWindow (Window, NULL);
InvalidateRect (StartupScreen, NULL, TRUE);
ST_Done = ST_Hexen_Done;
ST_Progress = ST_Heretic_Progress;
ST_HereticMessage = ST_Heretic_Message;
ST_HereticStatus = ST_Heretic_Status;
ST_NetInit = ST_Basic_NetInit;
ST_NetProgress = ST_Basic_NetProgress;
ST_NetMessage = ST_Basic_NetMessage;
ST_NetDone = ST_Basic_NetDone;
ST_NetLoop = ST_Basic_NetLoop;
hr = S_OK;
}
//==========================================================================
//
// ST_Heretic_Progress
// FHereticStartupScreen::Progress
//
// Bumps the progress meter one notch.
//
//==========================================================================
static void ST_Heretic_Progress()
void FHereticStartupScreen::Progress()
{
int notch_pos;
@ -869,13 +919,13 @@ static void ST_Heretic_Progress()
//==========================================================================
//
// ST_Heretic_Message
// FHereticStartupScreen :: LoadingStatus
//
// Prints text in the center box of the startup screen.
//
//==========================================================================
static void ST_Heretic_Message (const char *message, int attributes)
void FHereticStartupScreen::LoadingStatus(const char *message, int colors)
{
BYTE *font = ST_Util_LoadFont (TEXT_FONT_NAME);
if (font != NULL)
@ -884,7 +934,7 @@ static void ST_Heretic_Message (const char *message, int attributes)
for (x = 0; message[x] != '\0'; ++x)
{
ST_Util_DrawChar (StartupBitmap, font, 17 + x, HMsgY, message[x], attributes);
ST_Util_DrawChar (StartupBitmap, font, 17 + x, HMsgY, message[x], colors);
}
ST_Util_InvalidateRect (StartupScreen, StartupBitmap, 17 * 8, HMsgY * font[0], (17 + x) * 8, HMsgY * font[0] + font[0]);
ST_Util_FreeFont (font);
@ -895,13 +945,13 @@ static void ST_Heretic_Message (const char *message, int attributes)
//==========================================================================
//
// ST_Heretic_Status
// FHereticStartupScreen :: AppendStatusLine
//
// Appends text to Heretic's status line.
//
//==========================================================================
static void ST_Heretic_Status (const char *status)
void FHereticStartupScreen::AppendStatusLine(const char *status)
{
BYTE *font = ST_Util_LoadFont (TEXT_FONT_NAME);
if (font != NULL)
@ -921,10 +971,10 @@ static void ST_Heretic_Status (const char *status)
//==========================================================================
//
// ST_Strife_Init
// FStrifeStartupScreen Constructor
//
// Shows the Strife startup screen. If the screen doesn't appear to be
// valid, it falls back to ST_Basic_Init.
// valid, it returns a failure code in hr.
//
// The startup background is a raw 320x200 image, however Strife only
// actually uses 95 rows from it, starting at row 57. The rest of the image
@ -935,14 +985,20 @@ static void ST_Heretic_Status (const char *status)
//
//==========================================================================
static void ST_Strife_Init ()
FStrifeStartupScreen::FStrifeStartupScreen(int max_progress, HRESULT &hr)
: FGraphicalStartupScreen(max_progress)
{
int startup_lump = Wads.CheckNumForName ("STARTUP0");
int i;
hr = E_FAIL;
for (i = 0; i < 4+2+1; ++i)
{
StartupPics[i] = NULL;
}
if (startup_lump < 0 || Wads.LumpLength (startup_lump) != 64000 || !ST_Util_CreateStartupWindow())
{
ST_Basic_Init ();
return;
}
@ -961,77 +1017,52 @@ static void ST_Strife_Init ()
int lumpnum = Wads.CheckNumForName (StrifeStartupPicNames[i]);
int lumplen;
if (lumpnum < 0 || (lumplen = Wads.LumpLength (lumpnum)) != StrifeStartupPicSizes[i])
{
StrifeStartupPics[i] = NULL;
}
else
if (lumpnum >= 0 && (lumplen = Wads.LumpLength (lumpnum)) == StrifeStartupPicSizes[i])
{
FWadLump lumpr = Wads.OpenLumpNum (lumpnum);
StrifeStartupPics[i] = new BYTE[lumplen];
lumpr.Read (StrifeStartupPics[i], lumplen);
StartupPics[i] = new BYTE[lumplen];
lumpr.Read (StartupPics[i], lumplen);
}
}
// Make the startup image appear.
ST_Strife_DrawStuff (0, 0);
DrawStuff (0, 0);
ST_Util_SizeWindowForBitmap (2);
LayoutMainWindow (Window, NULL);
InvalidateRect (StartupScreen, NULL, TRUE);
ST_Done = ST_Strife_Done;
ST_Progress = ST_Strife_Progress;
ST_HereticMessage = ST_Basic_HereticMessage;
ST_HereticStatus = ST_Basic_HereticStatus;
ST_NetInit = ST_Basic_NetInit;
ST_NetProgress = ST_Basic_NetProgress;
ST_NetMessage = ST_Basic_NetMessage;
ST_NetDone = ST_Basic_NetDone;
ST_NetLoop = ST_Basic_NetLoop;
hr = S_OK;
}
//==========================================================================
//
// ST_Strife_Done
// FStrifeStartupScreen Deconstructor
//
// Called just before entering graphics mode to deconstruct the startup
// screen.
// Frees the strife pictures.
//
//==========================================================================
static void ST_Strife_Done()
FStrifeStartupScreen::~FStrifeStartupScreen()
{
int i;
for (i = 0; i < 4+2+1; ++i)
for (int i = 0; i < 4+2+1; ++i)
{
if (StrifeStartupPics[i] != NULL)
if (StartupPics[i] != NULL)
{
delete[] StrifeStartupPics[i];
delete[] StartupPics[i];
}
StrifeStartupPics[i] = NULL;
}
if (StartupScreen != NULL)
{
DestroyWindow (StartupScreen);
StartupScreen = NULL;
}
if (StartupBitmap != NULL)
{
ST_Util_FreeBitmap (StartupBitmap);
StartupBitmap = NULL;
StartupPics[i] = NULL;
}
}
//==========================================================================
//
// ST_Strife_Progress
// FStrifeStartupScreen :: Progress
//
// Bumps the progress meter one notch.
//
//==========================================================================
static void ST_Strife_Progress()
void FStrifeStartupScreen::Progress()
{
int notch_pos;
@ -1041,7 +1072,7 @@ static void ST_Strife_Progress()
notch_pos = (CurPos * (ST_LASERSPACE_WIDTH - ST_LASER_WIDTH)) / MaxPos;
if (notch_pos != NotchPos && !(notch_pos & 1))
{ // Time to update.
ST_Strife_DrawStuff (NotchPos, notch_pos);
DrawStuff (NotchPos, notch_pos);
NotchPos = notch_pos;
}
}
@ -1050,7 +1081,7 @@ static void ST_Strife_Progress()
//==========================================================================
//
// ST_Strife_DrawStuff
// FStrifeStartupScreen :: DrawStuff
//
// Draws all the moving parts of Strife's startup screen. If you're
// running off a slow drive, it can look kind of good. Otherwise, it
@ -1058,7 +1089,7 @@ static void ST_Strife_Progress()
//
//==========================================================================
static void ST_Strife_DrawStuff (int old_laser, int new_laser)
void FStrifeStartupScreen::DrawStuff(int old_laser, int new_laser)
{
int y;
@ -1066,7 +1097,7 @@ static void ST_Strife_DrawStuff (int old_laser, int new_laser)
ST_Util_ClearBlock (StartupBitmap, 0xF0, ST_LASERSPACE_X + old_laser,
ST_LASERSPACE_Y, ST_LASER_WIDTH, ST_LASER_HEIGHT);
// Draw new laser
ST_Util_DrawBlock (StartupBitmap, StrifeStartupPics[LASER_INDEX + (new_laser & 1)],
ST_Util_DrawBlock (StartupBitmap, StartupPics[LASER_INDEX + (new_laser & 1)],
ST_LASERSPACE_X + new_laser, ST_LASERSPACE_Y, ST_LASER_WIDTH, ST_LASER_HEIGHT);
// The bot jumps up and down like crazy.
@ -1075,7 +1106,7 @@ static void ST_Strife_DrawStuff (int old_laser, int new_laser)
{
ST_Util_ClearBlock (StartupBitmap, 0xF0, ST_BOT_X, ST_BOT_Y, ST_BOT_WIDTH, y);
}
ST_Util_DrawBlock (StartupBitmap, StrifeStartupPics[BOT_INDEX], ST_BOT_X, ST_BOT_Y + y, ST_BOT_WIDTH, ST_BOT_HEIGHT);
ST_Util_DrawBlock (StartupBitmap, StartupPics[BOT_INDEX], ST_BOT_X, ST_BOT_Y + y, ST_BOT_WIDTH, ST_BOT_HEIGHT);
if (y < (5 - 1) - 2)
{
ST_Util_ClearBlock (StartupBitmap, 0xF0, ST_BOT_X, ST_BOT_Y + ST_BOT_HEIGHT + y, ST_BOT_WIDTH, 2 - y);
@ -1083,7 +1114,7 @@ static void ST_Strife_DrawStuff (int old_laser, int new_laser)
// The peasant desperately runs in place, trying to get away from the laser.
// Yet, despite all his limb flailing, he never manages to get anywhere.
ST_Util_DrawBlock (StartupBitmap, StrifeStartupPics[PEASANT_INDEX + ((new_laser >> 1) & 3)],
ST_Util_DrawBlock (StartupBitmap, StartupPics[PEASANT_INDEX + ((new_laser >> 1) & 3)],
ST_PEASANT_X, ST_PEASANT_Y, ST_PEASANT_WIDTH, ST_PEASANT_HEIGHT);
}
@ -1107,6 +1138,7 @@ void ST_Endoom()
BYTE endoom_screen[4000];
BYTE *font;
MSG mess;
BOOL bRet;
if (endoom_lump < 0 || Wads.LumpLength (endoom_lump) != 4000)
{
@ -1130,7 +1162,6 @@ void ST_Endoom()
ST_Util_FreeFont (font);
exit(0);
}
ST_Done = ST_Basic_Done;
I_ShutdownGraphics ();
RestoreConView ();
@ -1156,20 +1187,22 @@ void ST_Endoom()
// Wait until any key has been pressed or a quit message has been received
while (1)
while ((bRet = GetMessage(&mess, NULL, 0, 0)) != 0)
{
if (PeekMessage (&mess, NULL, 0, 0, PM_REMOVE))
if (bRet == 0) // Received WM_QUIT
{
if (mess.message == WM_QUIT)
exit (int(mess.wParam));
}
else if (bRet != -1)
{
if (mess.message == WM_KEYDOWN || mess.message == WM_SYSKEYDOWN || mess.message == WM_LBUTTONDOWN)
exit(0);
{
exit (0);
}
}
TranslateMessage (&mess);
DispatchMessage (&mess);
}
else WaitMessage();
}
}
//==========================================================================
@ -1301,6 +1334,11 @@ void ST_Util_PlanarToChunky4 (BYTE *dest, const BYTE *src, int width, int height
void ST_Util_DrawBlock (BITMAPINFO *bitmap_info, const BYTE *src, int x, int y, int bytewidth, int height)
{
if (src == NULL)
{
return;
}
int pitchshift = int(bitmap_info->bmiHeader.biBitCount == 4);
int destpitch = bitmap_info->bmiHeader.biWidth >> pitchshift;
BYTE *dest = ST_Util_BitsForBitmap(bitmap_info) + (x >> pitchshift) + y * destpitch;