Note: I have not tried compiling these recent changes under Linux. I wouldn't

be surprised if it doesn't work.

- Reorganized the network startup loops so now they are event driven. There is
  a single function that gets called to drive it, and it uses callbacks to
  perform the different stages of the synchronization. This lets me have a nice,
  responsive abort button instead of the previous unannounced hit-escape-to-
  abort behavior, and I think the rearranged code is slightly easier to
  understand too.
- Increased the number of bytes for version info during D_ArbitrateNetStart(),
  in preparation for the day when NETGAMEVERSION requires more than one byte.
- I noticed an issue with Vista RC1 and the new fatal error setup. Even after
  releasing a DirectDraw or Direct3D interface, the DWM can still use the
  last image drawn using them when it composites the window. It doesn't always
  do it but it does often enough that it is a real problem. At this point, I
  don't know if it's a problem with the release version of Vista or not.
  After messing around, I discovered the problem was caused by ~Win32Video()
  hiding the window and then having it immediately shown soon after. The DWM
  kept an image of the window to do the transition effect with, and then when
  it didn't get a chance to do the transition, it didn't properly forget about
  its saved image and kept plastering it on top of everything else
  underneath.
- Added a network synchronization panel to the window during netgame startup.
- Fixed: PClass::CreateDerivedClass() must initialize StateList to NULL.
  Otherwise, classic DECORATE definitions generate a big, fat crash.
- Resurrected the R_Init progress bar, now as a standard Windows control.
- Removed the sound failure dialog. The FMOD setup already defaulted to no
  sound if initialization failed, so this only applies when snd_output is set
  to "alternate" which now also falls back to no sound. In addition, it wasn't
  working right, and I didn't feel like fixing it for the probably 0% of users
  it affected.
- Fixed: The edit control used for logging output added text in reverse order
  on Win9x.
- Went back to the roots and made graphics initialization one of the last
  things to happen during setup. Now the startup text is visible again. More
  importantly, the main window is no longer created invisible, which seems
  to cause trouble with it not always appearing in the taskbar. The fatal
  error dialog is now also embedded in the main window instead of being a
  separate modal dialog, so you can play with the log window to see any
  problems that might be reported there.
  
  Rather than completely restoring the original startup order, I tried to
  keep things as close to the way they were with early graphics startup. In
  particular, V_Init() now creates a dummy screen so that things that need
  screen dimensions can get them. It gets replaced by the real screen later
  in I_InitGraphics(). Will need to check this under Linux to make sure it
  didn't cause any problems there.
- Removed the following stubs that just called functions in Video:
    - I_StartModeIterator()
    - I_NextMode()
    - I_DisplayType()
  I_FullscreenChanged() was also removed, and a new fullscreen parameter
  was added to IVideo::StartModeIterator(), since that's all it controlled.
- Renamed I_InitHardware() back to I_InitGraphics(), since that's all it's
  initialized post-1.22.


SVN r416 (trunk)
This commit is contained in:
Randy Heit 2006-12-19 04:09:10 +00:00
parent e9c68df94e
commit 83373fba88
50 changed files with 2219 additions and 1031 deletions

View file

@ -1,3 +1,35 @@
December 18, 2006
- Reorganized the network startup loops so now they are event driven. There is
a single function that gets called to drive it, and it uses callbacks to
perform the different stages of the synchronization. This lets me have a nice,
responsive abort button instead of the previous unannounced hit-escape-to-
abort behavior, and I think the rearranged code is slightly easier to
understand too.
- Increased the number of bytes for version info during D_ArbitrateNetStart(),
in preparation for the day when NETGAMEVERSION requires more than one byte.
- I noticed an issue with Vista RC1 and the new fatal error setup. Even after
releasing a DirectDraw or Direct3D interface, the DWM can still use the
last image drawn using them when it composites the window. It doesn't always
do it but it does often enough that it is a real problem. At this point, I
don't know if it's a problem with the release version of Vista or not.
After messing around, I discovered the problem was caused by ~Win32Video()
hiding the window and then having it immediately shown soon after. The DWM
kept an image of the window to do the transition effect with, and then when
it didn't get a chance to do the transition, it didn't properly forget about
its saved image and kept plastering it on top of everything else
underneath.
December 16, 2006
- Added a network synchronization panel to the window during netgame startup.
- Fixed: PClass::CreateDerivedClass() must initialize StateList to NULL.
Otherwise, classic DECORATE definitions generate a big, fat crash.
- Resurrected the R_Init progress bar, now as a standard Windows control.
- Removed the sound failure dialog. The FMOD setup already defaulted to no
sound if initialization failed, so this only applies when snd_output is set
to "alternate" which now also falls back to no sound. In addition, it wasn't
working right, and I didn't feel like fixing it for the probably 0% of users
it affected.
December 16, 2006 (Changes by Graf Zahl)
- Fixed: The smartaim logic was incorrect. Also added another mode: Autoaim only
at monsters.
@ -16,6 +48,10 @@ December 16, 2006 (Changes by Graf Zahl)
at friendlies or shootable decorations if there are monsters that can be shot.
- Added: SetThingSpecial treats a tid of 0 as the activator.
December 15, 2006
- Fixed: The edit control used for logging output added text in reverse order
on Win9x.
December 13, 2006 (Changes by Graf Zahl)
- Fixed: The particle fountains' names were different than before
- Fixed: FTexture::CheckForTexture should return NULL if the texture it
@ -27,6 +63,30 @@ December 10, 2006 (Changes by Graf Zahl)
- Fixed: When a DehackedPickup replacement object is created it must copy
the state labels of the parent object.
December 9, 2006
- Went back to the roots and made graphics initialization one of the last
things to happen during setup. Now the startup text is visible again. More
importantly, the main window is no longer created invisible, which seems
to cause trouble with it not always appearing in the taskbar. The fatal
error dialog is now also embedded in the main window instead of being a
separate modal dialog, so you can play with the log window to see any
problems that might be reported there.
Rather than completely restoring the original startup order, I tried to
keep things as close to the way they were with early graphics startup. In
particular, V_Init() now creates a dummy screen so that things that need
screen dimensions can get them. It gets replaced by the real screen later
in I_InitGraphics(). Will need to check this under Linux to make sure it
didn't cause any problems there.
- Removed the following stubs that just called functions in Video:
- I_StartModeIterator()
- I_NextMode()
- I_DisplayType()
I_FullscreenChanged() was also removed, and a new fullscreen parameter
was added to IVideo::StartModeIterator(), since that's all it controlled.
- Renamed I_InitHardware() back to I_InitGraphics(), since that's all it's
initialized post-1.22.
December 9, 2006 (Changes by Graf Zahl)
- Fixed: P_LookForTid should abort its search when it discovers that it has
cycled through the entire list of actors.

View file

@ -414,11 +414,6 @@ void C_InitConsole (int width, int height, bool ingame)
if (fmtLines)
free (fmtLines);
}
if (ingame && gamestate == GS_STARTUP)
{
C_FullConsole ();
}
}
//==========================================================================
@ -857,7 +852,7 @@ int PrintString (int printlevel, const char *outline)
//#endif
}
I_PrintStr (outline, false);
I_PrintStr (outline);
AddToConsole (printlevel, outline);
if (vidactive && screen && screen->Font)
@ -1271,11 +1266,7 @@ void C_DrawConsole ()
if (ConBottom >= 20)
{
if (gamestate == GS_STARTUP)
{
screen->DrawText (CR_GREEN, LEFTMARGIN, bottomline, DoomStartupTitle, TAG_DONE);
}
else
if (gamestate != GS_STARTUP)
{
// Make a copy of the command line, in case an input event is handled
// while we draw the console and it changes.
@ -1350,9 +1341,7 @@ void C_ToggleConsole ()
void C_HideConsole ()
{
if (gamestate != GS_FULLCONSOLE &&
gamestate != GS_STARTUP &&
ConsoleState != c_up)
if (gamestate != GS_FULLCONSOLE)
{
ConsoleState = c_up;
ConBottom = 0;

View file

@ -86,6 +86,7 @@
#include "r_polymost.h"
#include "version.h"
#include "v_text.h"
#include "st_start.h"
// MACROS ------------------------------------------------------------------
@ -175,22 +176,23 @@ FTexture *Advisory;
cycle_t FrameCycles;
const char *IWADTypeNames[NUM_IWAD_TYPES] =
const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
{
"DOOM 2: TNT - Evilution",
"DOOM 2: Plutonia Experiment",
"Hexen: Beyond Heretic",
"Hexen: Deathkings of the Dark Citadel",
"DOOM 2: Hell on Earth",
"Heretic Shareware",
"Heretic: Shadow of the Serpent Riders",
"Heretic",
"DOOM Shareware",
"The Ultimate DOOM",
"DOOM Registered",
"Strife: Quest for the Sigil",
"Strife: Teaser (Old Version)",
"Strife: Teaser (New Version)"
// banner text, fg color, bg color
{ "DOOM 2: TNT - Evilution", MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "DOOM 2: Plutonia Experiment", MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "Hexen: Beyond Heretic", MAKERGB(240,240,240), MAKERGB(107,44,24) },
{ "Hexen: Deathkings of the Dark Citadel", MAKERGB(240,240,240), MAKERGB(139,68,9) },
{ "DOOM 2: Hell on Earth", MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "Heretic Shareware", MAKERGB(252,252,0), MAKERGB(168,0,0) },
{ "Heretic: Shadow of the Serpent Riders", MAKERGB(252,252,0), MAKERGB(168,0,0) },
{ "Heretic", MAKERGB(252,252,0), MAKERGB(168,0,0) },
{ "DOOM Shareware", MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "The Ultimate DOOM", MAKERGB(84,84,84), MAKERGB(168,168,168) },
{ "DOOM Registered", MAKERGB(84,84,84), MAKERGB(168,168,168) },
{ "Strife: Quest for the Sigil", MAKERGB(224,173,153), MAKERGB(0,107,101) },
{ "Strife: Teaser (Old Version)", MAKERGB(224,173,153), MAKERGB(0,107,101) },
{ "Strife: Teaser (New Version)", MAKERGB(224,173,153), MAKERGB(0,107,101) }
};
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -1958,6 +1960,8 @@ void D_DoomMain (void)
rngseed = (DWORD)time (NULL);
FRandom::StaticClearRandom ();
M_FindResponseFile ();
Printf ("M_LoadDefaults: Load system defaults.\n");
M_LoadDefaults (); // load before initing other systems
// [RH] Make sure zdoom.pk3 is always loaded,
@ -1969,11 +1973,9 @@ void D_DoomMain (void)
I_FatalError ("Cannot find " BASEWAD);
}
I_SetTitleString (IWADTypeNames[IdentifyVersion(wad)]);
I_SetIWADInfo (&IWADInfos[IdentifyVersion(wad)]);
GameConfig->DoGameSetup (GameNames[gameinfo.gametype]);
if (!(gameinfo.flags & GI_SHAREWARE))
{
// [RH] zvox.wad - A wad I had intended to be automatically generated
@ -2052,9 +2054,9 @@ void D_DoomMain (void)
delete files1;
delete files2;
Printf ("W_Init: Init WADfiles.\n");
Wads.InitMultipleFiles (&wadfiles);
// [RH] Initialize localizable strings.
GStrings.LoadStrings (false);
@ -2062,25 +2064,35 @@ void D_DoomMain (void)
// startup output in a fullscreen console.
CT_Init ();
Printf ("I_Init: Setting up machine state.\n");
I_Init ();
Printf ("V_Init: allocate screen.\n");
V_Init ();
// Base systems have been inited; enable cvar callbacks
FBaseCVar::EnableCallbacks ();
// [RH] Parse any SNDINFO lumps
Printf ("S_ParseSndInfo: Load sound definitions.\n");
S_ParseSndInfo ();
S_ParseSndEax ();
Printf ("S_Init: Setting up sound.\n");
S_Init ();
Printf ("ST_Init: Init startup screen.\n");
ST_Init (R_GuesstimateNumTextures() + 5);
// [RH] Now that all text strings are set up,
// insert them into the level and cluster data.
G_MakeEpisodes ();
// [RH] Parse through all loaded mapinfo lumps
Printf ("G_ParseMapInfo: Load map definitions.\n");
G_ParseMapInfo ();
// [RH] Parse any SNDINFO lumps
S_ParseSndInfo ();
S_ParseSndEax ();
FActorInfo::StaticInit ();
// [GRB] Initialize player class list
@ -2096,10 +2108,12 @@ void D_DoomMain (void)
}
FActorInfo::StaticGameSet ();
ST_Progress ();
Printf ("Init DOOM refresh subsystem.\n");
Printf ("R_Init: Init %s refresh subsystem\n", GameNames[gameinfo.gametype]);
R_Init ();
Printf ("DecalLibrary: Load decals.\n");
DecalLibrary.Clear ();
DecalLibrary.ReadAllDecals ();
@ -2161,7 +2175,8 @@ void D_DoomMain (void)
}
flags = dmflags;
Printf ("P_Init: Checking cmd-line parameters...\n");
if (Args.CheckParm ("-nomonsters")) flags |= DF_NO_MONSTERS;
if (Args.CheckParm ("-respawn")) flags |= DF_MONSTERS_RESPAWN;
if (Args.CheckParm ("-fast")) flags |= DF_FAST_MONSTERS;
@ -2224,7 +2239,6 @@ void D_DoomMain (void)
autostart = true;
}
//I_Error ("Oh gnos!");
// [RH] Hack to handle +map
p = Args.CheckParm ("+map");
if (p && p < Args.NumArgs()-1)
@ -2286,16 +2300,13 @@ void D_DoomMain (void)
timelimit = 20.f;
}
Printf ("Init miscellaneous info.\n");
Printf ("M_Init: Init miscellaneous info.\n");
M_Init ();
Printf ("Init Playloop state.\n");
Printf ("P_Init: Init Playloop state.\n");
P_Init ();
Printf ("Setting up sound.\n");
S_Init ();
Printf ("Checking network game status.\n");
Printf ("D_CheckNetGame: Checking network game status.\n");
D_CheckNetGame ();
// [RH] Lock any cvars that should be locked now that we're
@ -2319,6 +2330,9 @@ void D_DoomMain (void)
autostart = true;
}
ST_Done();
V_Init2();
files = Args.GatherFiles ("-playdemo", ".lmp", false);
if (files->NumArgs() > 0)
{
@ -2345,10 +2359,8 @@ void D_DoomMain (void)
G_LoadGame (file);
}
if (gameaction != ga_loadgame)
{
BorderNeedRefresh = screen->GetPageCount ();
if (autostart || netgame)
{
CheckWarpTransMap (startmap, true);

View file

@ -83,6 +83,13 @@ struct WadStuff
EIWADType Type;
};
extern const char *IWADTypeNames[NUM_IWAD_TYPES];
struct IWADInfo
{
const char *Name; // Title banner text for this IWAD
DWORD FgColor; // Foreground color for title banner
DWORD BkColor; // Background color for title banner
};
extern const IWADInfo IWADInfos[NUM_IWAD_TYPES];
#endif

View file

@ -51,6 +51,7 @@
#include "p_acs.h"
#include "p_trace.h"
#include "a_sharedglobal.h"
#include "st_start.h"
int P_StartScript (AActor *who, line_t *where, int script, char *map, bool backSide,
int arg0, int arg1, int arg2, int always, bool wantResultCode, bool net);
@ -1263,53 +1264,17 @@ void NetUpdate (void)
}
//
// CheckAbort
//
bool CheckAbort (void)
{
event_t *ev;
bool res = false;
PrintString (PRINT_HIGH, ""); // [RH] Give the console a chance to redraw itself
// This WaitForTic is to avoid flooding the network with packets on startup.
I_WaitForTic (I_GetTime (false) + TICRATE/4);
I_StartTic ();
for ( ; eventtail != eventhead
; eventtail = (eventtail+1)&(MAXEVENTS-1) )
{
ev = &events[eventtail];
if (ev->type == EV_KeyDown && ev->data1 == KEY_ESCAPE)
{
res = true;
break;
}
if (ev->type == EV_GUI_Event &&
(ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) &&
ev->data1 == GK_ESCAPE)
{
res = true;
break;
}
}
eventhead = eventtail = 0;
return res;
}
//
// D_ArbitrateNetStart
//
// User info packets look like this:
//
// 0 One byte set to NCMD_SETUP or NCMD_SETUP+1
// If NCMD_SETUP+1, omit byte 7
// 0 One byte set to NCMD_SETUP or NCMD_SETUP+1; if NCMD_SETUP+1, omit byte 9
// 1 One byte for the player's number
// 2 One byte for the game version
//3-7 A bit mask for each player the sender knows about
// (the high bit of byte 7 indicates the game info was received)
// 8 A stream of bytes with the user info
//2-4 Three bytes for the game version (255,high byte,low byte)
//5-8 A bit mask for each player the sender knows about
// 9 The high bit is set if the sender got the game info
// 10 A stream of bytes with the user info
//
// The guests always send NCMD_SETUP packets, and the host always
// sends NCMD_SETUP+1 packets.
@ -1333,15 +1298,158 @@ bool CheckAbort (void)
// Negotiation is done when all the guests have reported to the host that
// they know about the other nodes.
struct ArbitrateData
{
DWORD playersdetected[MAXNETNODES];
BYTE gotsetup[MAXNETNODES];
};
bool DoArbitrate (void *userdata)
{
ArbitrateData *data = (ArbitrateData *)userdata;
char *s;
BYTE *stream;
int version;
int node;
int i, j;
while (HGetPacket ())
{
if (netbuffer[0] == NCMD_EXIT)
{
I_FatalError ("The game was aborted.");
}
if (doomcom.remotenode == 0)
{
continue;
}
if (netbuffer[0] == NCMD_SETUP || netbuffer[0] == NCMD_SETUP+1) // got user info
{
node = (netbuffer[0] == NCMD_SETUP) ? doomcom.remotenode : nodeforplayer[netbuffer[1]];
data->playersdetected[node] =
(netbuffer[5] << 24) | (netbuffer[6] << 16) | (netbuffer[7] << 8) | netbuffer[8];
if (netbuffer[0] == NCMD_SETUP)
{ // Sent to host
data->gotsetup[node] = netbuffer[9] & 0x80;
stream = &netbuffer[10];
}
else
{ // Sent from host
stream = &netbuffer[9];
}
if (!nodeingame[node])
{
version = (netbuffer[2] << 16) | (netbuffer[3] << 8) | netbuffer[4];
if (version != (0xFF0000 | NETGAMEVERSION))
{
I_Error ("Different " GAMENAME " versions cannot play a net game");
}
playeringame[netbuffer[1]] = true;
nodeingame[node] = true;
data->playersdetected[0] |= 1 << netbuffer[1];
D_ReadUserInfoStrings (netbuffer[1], &stream, false);
Printf ("Found %s (node %d, player %d)\n",
players[netbuffer[1]].userinfo.netname,
node, netbuffer[1]+1);
}
}
else if (netbuffer[0] == NCMD_SETUP+2) // got game info
{
data->gotsetup[0] = 0x80;
ticdup = doomcom.ticdup = netbuffer[1];
doomcom.extratics = netbuffer[2];
NetMode = netbuffer[3];
stream = &netbuffer[4];
s = ReadString (&stream);
strncpy (startmap, s, 8);
delete[] s;
rngseed = ReadLong (&stream);
C_ReadCVars (&stream);
}
else if (netbuffer[0] == NCMD_SETUP+3)
{
return true;
}
}
// If everybody already knows everything, it's time to go
if (consoleplayer == Net_Arbitrator)
{
for (i = 0; i < doomcom.numnodes; ++i)
if (data->playersdetected[i] != DWORD(1 << doomcom.numnodes) - 1 || !data->gotsetup[i])
break;
if (i == doomcom.numnodes)
return true;
}
netbuffer[2] = 255;
netbuffer[3] = (NETGAMEVERSION >> 8) & 255;
netbuffer[4] = NETGAMEVERSION & 255;
netbuffer[5] = data->playersdetected[0] >> 24;
netbuffer[6] = data->playersdetected[0] >> 16;
netbuffer[7] = data->playersdetected[0] >> 8;
netbuffer[8] = data->playersdetected[0];
if (consoleplayer != Net_Arbitrator)
{ // Send user info for the local node
netbuffer[0] = NCMD_SETUP;
netbuffer[1] = consoleplayer;
netbuffer[9] = data->gotsetup[0];
stream = &netbuffer[10];
D_WriteUserInfoStrings (consoleplayer, &stream, true);
SendSetup (data->playersdetected, data->gotsetup, stream - netbuffer);
}
else
{ // Send user info for all nodes
netbuffer[0] = NCMD_SETUP+1;
for (i = 1; i < doomcom.numnodes; ++i)
{
for (j = 0; j < doomcom.numnodes; ++j)
{
// Send info about player j to player i?
if (i != j && (data->playersdetected[0] & (1<<j)) && !(data->playersdetected[i] & (1<<j)))
{
netbuffer[1] = j;
stream = &netbuffer[9];
D_WriteUserInfoStrings (j, &stream, true);
HSendPacket (i, stream - netbuffer);
}
}
}
}
// If we're the host, send the game info, too
if (consoleplayer == Net_Arbitrator)
{
netbuffer[0] = NCMD_SETUP+2;
netbuffer[1] = doomcom.ticdup;
netbuffer[2] = doomcom.extratics;
netbuffer[3] = NetMode;
stream = &netbuffer[4];
WriteString (startmap, &stream);
WriteLong (rngseed, &stream);
C_WriteCVars (&stream, CVAR_SERVERINFO, true);
SendSetup (data->playersdetected, data->gotsetup, stream - netbuffer);
}
return false;
}
void D_ArbitrateNetStart (void)
{
int i, j;
DWORD playersdetected[MAXNETNODES];
BYTE gotsetup[MAXNETNODES];
char *s;
BYTE *stream;
int node;
bool allset = false;
ArbitrateData data;
int i;
// Return right away if we're just playing with ourselves.
if (doomcom.numnodes == 1)
@ -1349,13 +1457,16 @@ void D_ArbitrateNetStart (void)
autostart = true;
memset (playersdetected, 0, sizeof(playersdetected));
memset (gotsetup, 0, sizeof(gotsetup));
memset (data.playersdetected, 0, sizeof(data.playersdetected));
memset (data.gotsetup, 0, sizeof(data.gotsetup));
// Everyone know about themself
playersdetected[0] = 1 << consoleplayer;
data.playersdetected[0] = 1 << consoleplayer;
// Assign nodes to players
// Assign nodes to players. The local player is always node 0.
// If the local player is not the host, then the host is node 1.
// Any remaining players are assigned node numbers in the order
// they were detected.
playerfornode[0] = consoleplayer;
nodeforplayer[consoleplayer] = 0;
if (consoleplayer == Net_Arbitrator)
@ -1387,150 +1498,19 @@ void D_ArbitrateNetStart (void)
if (consoleplayer == Net_Arbitrator)
{
gotsetup[0] = 0x80;
data.gotsetup[0] = 0x80;
}
while (!allset)
ST_NetInit ("Exchanging game information", 1);
if (!ST_NetLoop (DoArbitrate, &data))
{
if (CheckAbort ())
I_FatalError ("Network game synchronization aborted.");
I_WaitVBL (1);
while (HGetPacket ())
{
if (netbuffer[0] == NCMD_EXIT)
{
I_FatalError ("The game was aborted\n");
}
if (doomcom.remotenode == 0)
{
continue;
}
if (netbuffer[0] == NCMD_SETUP || netbuffer[0] == NCMD_SETUP+1) // got user info
{
node = (netbuffer[0] == NCMD_SETUP) ? doomcom.remotenode
: nodeforplayer[netbuffer[1]];
playersdetected[node] =
(netbuffer[3] << 24) | (netbuffer[4] << 16) | (netbuffer[5] << 8) | netbuffer[6];
if (netbuffer[0] == NCMD_SETUP)
{ // Sent to host
gotsetup[node] = netbuffer[7] & 0x80;
stream = &netbuffer[8];
}
else
{ // Sent from host
stream = &netbuffer[7];
}
if (!nodeingame[node])
{
if (netbuffer[2] != NETGAMEVERSION)
I_Error ("Different DOOM versions cannot play a net game!");
playeringame[netbuffer[1]] = true;
nodeingame[node] = true;
playersdetected[0] |= 1 << netbuffer[1];
D_ReadUserInfoStrings (netbuffer[1], &stream, false);
Printf ("Found %s (node %d, player %d)\n",
players[netbuffer[1]].userinfo.netname,
node, netbuffer[1]+1);
}
}
else if (netbuffer[0] == NCMD_SETUP+2) // got game info
{
gotsetup[0] = 0x80;
ticdup = doomcom.ticdup = netbuffer[1];
doomcom.extratics = netbuffer[2];
NetMode = netbuffer[3];
stream = &netbuffer[4];
s = ReadString (&stream);
strncpy (startmap, s, 8);
delete[] s;
rngseed = ReadLong (&stream);
C_ReadCVars (&stream);
}
else if (netbuffer[0] == NCMD_SETUP+3)
{
allset = true;
}
}
// If everybody already knows everything, it's time to go
if (consoleplayer == Net_Arbitrator)
{
for (i = 0; i < doomcom.numnodes; ++i)
if (playersdetected[i] != DWORD(1 << doomcom.numnodes) - 1 || !gotsetup[i])
break;
if (i == doomcom.numnodes)
break;
}
netbuffer[2] = NETGAMEVERSION;
netbuffer[3] = playersdetected[0] >> 24;
netbuffer[4] = playersdetected[0] >> 16;
netbuffer[5] = playersdetected[0] >> 8;
netbuffer[6] = playersdetected[0];
if (!allset && consoleplayer != Net_Arbitrator)
{ // Send user info for the local node
netbuffer[0] = NCMD_SETUP;
netbuffer[1] = consoleplayer;
netbuffer[7] = gotsetup[0];
stream = &netbuffer[8];
D_WriteUserInfoStrings (consoleplayer, &stream, true);
SendSetup (playersdetected, gotsetup, stream - netbuffer);
}
else
{ // Send user info for all nodes
netbuffer[0] = NCMD_SETUP+1;
netbuffer[2] = NETGAMEVERSION;
for (i = 1; i < doomcom.numnodes; ++i)
{
for (j = 0; j < doomcom.numnodes; ++j)
{
// Send info about player j to player i?
if (i != j && (playersdetected[0] & (1<<j)) &&
!(playersdetected[i] & (1<<j)))
{
netbuffer[1] = j;
stream = &netbuffer[7];
D_WriteUserInfoStrings (j, &stream, true);
HSendPacket (i, stream - netbuffer);
}
}
}
}
// If we're the host, send the game info, too
if (consoleplayer == Net_Arbitrator)
{
netbuffer[0] = NCMD_SETUP+2;
netbuffer[1] = doomcom.ticdup;
netbuffer[2] = doomcom.extratics;
netbuffer[3] = NetMode;
stream = &netbuffer[4];
WriteString (startmap, &stream);
WriteLong (rngseed, &stream);
C_WriteCVars (&stream, CVAR_SERVERINFO, true);
SendSetup (playersdetected, gotsetup, stream - netbuffer);
}
exit (0);
}
if (consoleplayer == Net_Arbitrator)
{
netbuffer[0] = NCMD_SETUP+3;
SendSetup (playersdetected, gotsetup, 1);
SendSetup (data.playersdetected, data.gotsetup, 1);
}
if (debugfile)
@ -1540,6 +1520,7 @@ void D_ArbitrateNetStart (void)
fprintf (debugfile, "player %d is on node %d\n", i, nodeforplayer[i]);
}
}
ST_NetDone();
}
static void SendSetup (DWORD playersdetected[MAXNETNODES], BYTE gotsetup[MAXNETNODES], int len)
@ -1548,7 +1529,7 @@ static void SendSetup (DWORD playersdetected[MAXNETNODES], BYTE gotsetup[MAXNETN
{
if (playersdetected[1] & (1 << consoleplayer))
{
HSendPacket (1, 8);
HSendPacket (1, 10);
}
else
{

View file

@ -237,6 +237,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
info->NumOwnedStates = 0;
info->Replacement = NULL;
info->Replacee = NULL;
info->StateList = NULL;
m_RuntimeActors.Push (type);
}
return type;

View file

@ -59,6 +59,7 @@
#include "d_player.h"
#include "templates.h"
#include "c_console.h"
#include "st_start.h"
#include "doomstat.h"
@ -84,9 +85,6 @@ typedef int SOCKET;
typedef int socklen_t;
#endif
extern bool CheckAbort (void);
//
// NETWORKING
//
@ -121,7 +119,11 @@ struct PreGamePacket
BYTE fake;
BYTE message;
BYTE numnodes;
BYTE consolenum;
union
{
BYTE consolenum;
BYTE numack;
};
struct
{
u_long address;
@ -306,7 +308,7 @@ void BuildAddress (sockaddr_in *address, char *name)
if (!isnamed)
{
address->sin_addr.s_addr = inet_addr (name);
Printf ("Node number %d address %s\n", doomcom.numnodes, name);
Printf ("Node number, %d address %s\n", doomcom.numnodes, name);
}
else
{
@ -396,14 +398,152 @@ void SendAbort (void)
}
}
bool Host_CheckForConnects (void *userdata)
{
PreGamePacket packet;
int numplayers = (int)(intptr_t)userdata;
sockaddr_in *from;
int node;
while ( (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake != PRE_FAKE)
{
continue;
}
switch (packet.message)
{
case PRE_CONNECT:
node = FindNode (from);
if (node == -1)
{
node = doomcom.numnodes++;
sendaddress[node] = *from;
}
Printf ("Got connect from node %d\n", node);
packet.message = PRE_CONACK;
packet.numnodes = numplayers;
packet.consolenum = node;
PreSend (&packet, 4, from);
ST_NetProgress (doomcom.numnodes);
break;
case PRE_DISCONNECT:
node = FindNode (from);
if (node >= 0)
{
Printf ("Got disconnect from node %d\n", node);
doomcom.numnodes--;
while (node < doomcom.numnodes)
{
sendaddress[node] = sendaddress[node+1];
node++;
}
ST_NetProgress (doomcom.numnodes);
}
break;
}
}
if (doomcom.numnodes < numplayers)
{
return false;
}
// It's possible somebody bailed out after all players were found.
// Unfortunately, this isn't guaranteed to catch all of them.
// Oh well. Better than nothing.
while ( (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake == PRE_FAKE && packet.message == PRE_DISCONNECT)
{
node = FindNode (from);
if (node >= 0)
{
doomcom.numnodes--;
while (node < doomcom.numnodes)
{
sendaddress[node] = sendaddress[node+1];
node++;
}
}
break;
}
}
return doomcom.numnodes >= numplayers;
}
bool Host_SendAllHere (void *userdata)
{
int *gotack = (int *)userdata; // ackcount is at gotack[MAXNETNODES]
PreGamePacket packet;
int node;
sockaddr_in *from;
for (node = 1, packet.numack = 1; node < doomcom.numnodes; ++node)
{
packet.numack += gotack[node];
}
// Send out address information to all guests. Guests that have already
// acknowledged receipt effectively get just a heartbeat packet.
packet.fake = PRE_FAKE;
packet.message = PRE_ALLHERE;
for (node = 1; node < doomcom.numnodes; node++)
{
int machine, spot = 0;
if (!gotack[node])
{
for (spot = 0, machine = 1; machine < doomcom.numnodes; machine++)
{
if (node != machine)
{
packet.machines[spot].address = sendaddress[machine].sin_addr.s_addr;
packet.machines[spot].port = sendaddress[machine].sin_port;
packet.machines[spot].player = node;
spot++; // fixes problem of new address replacing existing address in
// array; it's supposed to increment the index before getting
// and storing in the packet the next address.
}
}
packet.numnodes = doomcom.numnodes - 2;
}
else
{
packet.numnodes = 0;
}
PreSend (&packet, 4 + spot*8, &sendaddress[node]);
}
// Check for replies.
while ( (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake == PRE_FAKE && packet.message == PRE_ALLHEREACK)
{
node = FindNode (from);
if (node >= 0)
{
if (!gotack[node])
{
gotack[node] = true;
gotack[MAXNETNODES]++;
}
}
PreSend (&packet, 2, from);
}
}
// If everybody has replied, then this loop can end.
return gotack[MAXNETNODES] == doomcom.numnodes - 1;
}
void HostGame (int i)
{
PreGamePacket packet;
int numplayers;
bool gotack[MAXNETNODES];
int ackcount;
sockaddr_in *from;
int node;
int gotack[MAXNETNODES+1];
if ((i == Args.NumArgs() - 1) || !(numplayers = atoi (Args.GetArg(i+1))))
{ // No player count specified, assume 2
@ -432,136 +572,22 @@ void HostGame (int i)
atterm (SendAbort);
C_InitTicker ("Waiting for players", numplayers);
C_SetTicker (1, true);
ST_NetInit ("Waiting for players", numplayers);
// Wait for numplayers-1 different connections
while (doomcom.numnodes < numplayers)
if (!ST_NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers))
{
while (doomcom.numnodes < numplayers)
{
C_SetTicker (doomcom.numnodes, true);
if (CheckAbort ())
{
SendAbort ();
I_FatalError ("Network game synchronization aborted.");
}
while ( (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake != PRE_FAKE)
{
continue;
}
switch (packet.message)
{
case PRE_CONNECT:
node = FindNode (from);
if (node == -1)
{
node = doomcom.numnodes++;
sendaddress[node] = *from;
}
Printf ("Got connect from node %d\n", node);
packet.message = PRE_CONACK;
packet.consolenum = node;
PreSend (&packet, 4, from);
break;
case PRE_DISCONNECT:
node = FindNode (from);
if (node >= 0)
{
Printf ("Got disconnect from node %d\n", node);
doomcom.numnodes--;
while (node < doomcom.numnodes)
{
sendaddress[node] = sendaddress[node+1];
node++;
}
}
break;
}
}
}
// It's possible somebody bailed out after all players were found.
// Unfortunately, this isn't guaranteed to catch all of them.
// Oh well. Better than nothing.
while ( (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake == PRE_FAKE && packet.message == PRE_DISCONNECT)
{
node = FindNode (from);
if (node >= 0)
{
doomcom.numnodes--;
while (node < doomcom.numnodes)
{
sendaddress[node] = sendaddress[node+1];
node++;
}
}
break;
}
}
exit (0);
}
// Now inform everyone of all machines involved in the game
ackcount = 0;
memset (gotack, 0, sizeof(gotack));
Printf ("Sending all here\n");
C_InitTicker ("Done waiting", 1);
C_SetTicker (1, true);
while (ackcount < doomcom.numnodes - 1)
ST_NetInit ("Done waiting", 1);
if (!ST_NetLoop (Host_SendAllHere, (void *)gotack))
{
packet.fake = PRE_FAKE;
packet.message = PRE_ALLHERE;
packet.numnodes = doomcom.numnodes - 2;
for (node = 1; node < doomcom.numnodes; node++)
{
int machine, spot = 0;
if (!gotack[node])
{
for (spot = 0, machine = 1; machine < doomcom.numnodes; machine++)
{
if (node != machine)
{
packet.machines[spot].address = sendaddress[machine].sin_addr.s_addr;
packet.machines[spot].port = sendaddress[machine].sin_port;
packet.machines[spot].player = node;
spot++; // fixes problem of new address replacing existing address in
// array, it's supposed to increment the index before getting
// and storing in the packet the next address.
}
}
}
PreSend (&packet, 4 + spot*8, &sendaddress[node]);
}
if (CheckAbort ())
{
SendAbort ();
I_FatalError ("Network game synchronization aborted.");
}
while ( (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake == PRE_FAKE && packet.message == PRE_ALLHEREACK)
{
node = FindNode (from);
if (node >= 0)
{
if (!gotack[node])
{
gotack[node] = true;
ackcount++;
}
}
PreSend (&packet, 2, from);
}
}
exit (0);
}
popterm ();
@ -572,6 +598,8 @@ void HostGame (int i)
packet.message = PRE_GO;
for (node = 1; node < doomcom.numnodes; node++)
{
// If we send the packets eight times to each guest,
// hopefully at least one of them will get through.
for (int i = 8; i != 0; --i)
{
PreSend (&packet, 2, &sendaddress[node]);
@ -588,84 +616,97 @@ void HostGame (int i)
{
sendplayer[i] = i;
}
C_SetTicker (1, true);
C_InitTicker (NULL, 0);
}
// This routine is used by a guest to notify the host of its presence.
// Once that host acknowledges receipt of the notification, this routine
// is never called again.
static const int bouncerfps = 10;
static const int bouncerdelay = 1000 / bouncerfps;
static const int updateperiod = 300 / bouncerdelay;
int SendToHost (BYTE message, BYTE ackmess, bool abortable)
bool Guest_ContactHost (void *userdata)
{
sockaddr_in *from;
bool waiting = true;
PreGamePacket packet;
int bouncer = 0;
C_InitTicker ("Waiting for host", 8, false);
C_SetTicker (0, true);
// Let host know we are here
// Let the host know we are here.
packet.fake = PRE_FAKE;
packet.message = message;
packet.message = PRE_CONNECT;
PreSend (&packet, 2, &sendaddress[1]);
while (waiting)
// Listen for a reply.
while ( (from = PreGet (&packet, sizeof(packet), true)) )
{
if (abortable && CheckAbort ())
if (packet.fake == PRE_FAKE && packet.message == PRE_CONACK)
{
SendAbort ();
I_FatalError ("Network game synchronization aborted.");
}
Sleep (bouncerdelay);
// Listen for acknowledgement
if (bouncer % updateperiod == 0)
{
while ( (from = PreGet (&packet, sizeof(packet), true)) )
{
if (packet.fake == PRE_FAKE && packet.message == ackmess)
{
waiting = false;
doomcom.consoleplayer = packet.consolenum;
sendplayer[0] = packet.consolenum;
Printf ("Console player number: %d\n", doomcom.consoleplayer);
}
}
if (waiting)
{
// Let host know we are here
packet.fake = PRE_FAKE;
packet.message = message;
PreSend (&packet, 2, &sendaddress[1]);
}
}
if (waiting)
{
int tickpos = ++bouncer & 15;
if (tickpos > 8)
{
tickpos = 16 - tickpos;
}
C_SetTicker (tickpos, true);
doomcom.consoleplayer = packet.consolenum;
sendplayer[0] = packet.consolenum;
Printf ("Console player number: %d\n", doomcom.consoleplayer);
*(int *)userdata = packet.numnodes; // Really # of players in the game.
return true;
}
}
return bouncer;
// In case the progress bar could not be marqueed, bump it.
ST_NetProgress (0);
return false;
}
bool Guest_WaitForOthers (void *userdata)
{
sockaddr_in *from;
PreGamePacket packet;
while ( (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake != PRE_FAKE)
{
continue;
}
switch (packet.message)
{
case PRE_ALLHERE:
if (doomcom.numnodes == 0)
{
int node;
packet.numnodes = packet.numnodes;
doomcom.numnodes = packet.numnodes + 2;
for (node = 0; node < packet.numnodes; node++)
{
sendaddress[node+2].sin_addr.s_addr = packet.machines[node].address;
sendaddress[node+2].sin_port = packet.machines[node].port;
sendplayer[node+2] = packet.machines[node].player;
// [JC] - fixes problem of games not starting due to
// no address family being assigned to nodes stored in
// sendaddress[] from the All Here packet.
sendaddress[node+2].sin_family = AF_INET;
}
}
ST_NetProgress (packet.numack);
Printf ("Received All Here, sending ACK\n");
packet.fake = PRE_FAKE;
packet.message = PRE_ALLHEREACK;
PreSend (&packet, 2, &sendaddress[1]);
break;
case PRE_GO:
Printf ("Go\n");
return true;
case PRE_DISCONNECT:
I_FatalError ("Host cancelled the game");
break;
}
}
return false;
}
void JoinGame (int i)
{
sockaddr_in *from;
bool waiting;
PreGamePacket packet;
int bouncer;
int numplayers = 0;
if ((i == Args.NumArgs() - 1) ||
(Args.GetArg(i+1)[0] == '-') ||
@ -678,85 +719,31 @@ void JoinGame (int i)
BuildAddress (&sendaddress[1], Args.GetArg(i+1));
sendplayer[1] = 0;
// Let host know we are here
bouncer = SendToHost (PRE_CONNECT, PRE_CONACK, true);
// Wait for everyone else to connect
C_InitTicker ("Waiting for players", 8, false);
waiting = true;
//doomcom.numnodes = 2;
atterm (SendAbort);
while (waiting)
// Let host know we are here
ST_NetInit ("Contacting host", 0);
if (!ST_NetLoop (Guest_ContactHost, &numplayers))
{
if (CheckAbort ())
{
SendAbort ();
I_FatalError ("Network game synchronization aborted.");
}
exit (0);
}
Sleep (bouncerdelay);
// Wait for everyone else to connect
Printf ("Total players: %d\n", numplayers);
ST_NetInit ("Waiting for players", numplayers);
if (bouncer % updateperiod == 0)
{
while (waiting && (from = PreGet (&packet, sizeof(packet), false)) )
{
if (packet.fake != PRE_FAKE)
{
continue;
}
switch (packet.message)
{
case PRE_ALLHERE:
if (doomcom.numnodes == 0)
{
int node;
// We know about ourself and the host; that's two players.
ST_NetProgress (2);
packet.numnodes = packet.numnodes;
doomcom.numnodes = packet.numnodes + 2;
for (node = 0; node < packet.numnodes; node++)
{
sendaddress[node+2].sin_addr.s_addr = packet.machines[node].address;
sendaddress[node+2].sin_port = packet.machines[node].port;
sendplayer[node+2] = packet.machines[node].player;
// [JC] - fixes problem of games not starting due to
// no address family being assigned to nodes stored in
// sendaddress[] from the All Here packet.
sendaddress[node+2].sin_family = AF_INET;
}
}
Printf ("Received All Here, sending ACK\n");
packet.fake = PRE_FAKE;
packet.message = PRE_ALLHEREACK;
PreSend (&packet, 2, &sendaddress[1]);
break;
case PRE_GO:
Printf ("Go\n");
waiting = false;
break;
case PRE_DISCONNECT:
I_FatalError ("Host cancelled the game");
break;
}
}
}
if (waiting)
{
int tickpos = ++bouncer & 15;
if (tickpos > 8)
{
tickpos = 16 - tickpos;
}
C_SetTicker (tickpos, true);
}
if (!ST_NetLoop (Guest_WaitForOthers, 0))
{
exit (0);
}
popterm ();
Printf ("Total players: %d\n", doomcom.numnodes);
C_InitTicker (NULL, 0);
doomcom.id = DOOMCOM_ID;
doomcom.numplayers = doomcom.numnodes;

View file

@ -38,11 +38,6 @@ void I_WaitVBL(int count);
bool I_CheckResolution (int width, int height, int bpp);
void I_ClosestResolution (int *width, int *height, int bits);
void I_StartModeIterator (int bits);
bool I_NextMode (int *width, int *height, bool *fullscreen);
DCanvas *I_NewStaticCanvas (int width, int height);
enum EDisplayType
{
DISPLAY_WindowOnly,
@ -50,6 +45,4 @@ enum EDisplayType
DISPLAY_Both
};
EDisplayType I_DisplayType ();
#endif // __I_VIDEO_H__

View file

@ -276,6 +276,7 @@ void FActorInfo::StaticInit ()
reg->BuildDefaults ();
}
Printf ("LoadDecorations: Load external actors.\n");
LoadDecorations (ProcessStates);
}

View file

@ -68,6 +68,9 @@ void M_OptDrawer (void);
// [RH] Initialize options menu
void M_OptInit (void);
// [RH] Initialize the video modes menu
void M_InitVideoModesMenu (void);
struct menu_s;
void M_SwitchMenu (struct menu_s *menu);

View file

@ -75,6 +75,7 @@
#include "doomstat.h"
#include "m_misc.h"
#include "hardware.h"
// Data.
#include "m_menu.h"
@ -917,7 +918,6 @@ CUSTOM_CVAR (Bool, vid_tft, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
menu_screenratios = 0;
}
}
BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
}
/*=======================================
@ -1211,39 +1211,6 @@ static BYTE BitTranslate[16];
void M_OptInit (void)
{
int dummy1, dummy2;
size_t currval = 0;
char name[24];
for (unsigned int i = 1; i < 32 && currval < countof(Depths); i++)
{
I_StartModeIterator (i);
if (I_NextMode (&dummy1, &dummy2, NULL))
{
Depths[currval].value = currval;
sprintf (name, "%d bit", i);
Depths[currval].name = copystring (name);
BitTranslate[currval] = i;
currval++;
}
}
//ModesItems[VM_DEPTHITEM].b.min = (float)currval;
switch (I_DisplayType ())
{
case DISPLAY_FullscreenOnly:
ModesItems[2].type = nochoice;
ModesItems[2].b.min = 1.f;
break;
case DISPLAY_WindowOnly:
ModesItems[2].type = nochoice;
ModesItems[2].b.min = 0.f;
break;
default:
break;
}
if (gameinfo.gametype == GAME_Doom)
{
LabelColor = CR_UNTRANSLATED;
@ -1264,6 +1231,44 @@ void M_OptInit (void)
}
}
void M_InitVideoModesMenu ()
{
int dummy1, dummy2;
size_t currval = 0;
char name[24];
M_RefreshModesList();
for (unsigned int i = 1; i < 32 && currval < countof(Depths); i++)
{
Video->StartModeIterator (i, screen->IsFullscreen());
if (Video->NextMode (&dummy1, &dummy2, NULL))
{
Depths[currval].value = currval;
sprintf (name, "%d bit", i);
Depths[currval].name = copystring (name);
BitTranslate[currval] = i;
currval++;
}
}
//ModesItems[VM_DEPTHITEM].b.min = (float)currval;
switch (Video->GetDisplayType ())
{
case DISPLAY_FullscreenOnly:
ModesItems[2].type = nochoice;
ModesItems[2].b.min = 1.f;
break;
case DISPLAY_WindowOnly:
ModesItems[2].type = nochoice;
ModesItems[2].b.min = 0.f;
break;
default:
break;
}
}
//
// Toggle messages on/off
@ -2807,14 +2812,17 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits)
}
showbits = BitTranslate[DummyDepthCvar];
I_StartModeIterator (showbits);
if (Video != NULL)
{
Video->StartModeIterator (showbits, screen->IsFullscreen());
}
for (i = VM_RESSTART; ModesItems[i].type == screenres; i++)
{
ModesItems[i].e.highlight = -1;
for (c = 0; c < 3; c++)
{
bool haveMode;
bool haveMode = false;
switch (c)
{
@ -2822,9 +2830,12 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits)
case 1: str = &ModesItems[i].c.res2; break;
case 2: str = &ModesItems[i].d.res3; break;
}
while ((haveMode = I_NextMode (&width, &height, &letterbox)) &&
(ratiomatch >= 0 && CheckRatio (width, height) != ratiomatch))
if (Video != NULL)
{
while ((haveMode = Video->NextMode (&width, &height, &letterbox)) &&
(ratiomatch >= 0 && CheckRatio (width, height) != ratiomatch))
{
}
}
if (haveMode)

View file

@ -53,10 +53,18 @@
#include "gi.h"
#include "cmdlib.h"
#include "templates.h"
#include "st_start.h"
static void R_InitPatches ();
void R_InitBuildTiles();
void R_DeinitBuildTiles();
static int R_CountGroup (const char *start, const char *end);
static int R_CountTexturesX ();
static int R_CountLumpTextures (int lumpnum);
extern void R_InitBuildTiles();
extern void R_DeinitBuildTiles();
extern int R_CountBuildTiles();
//
// Graphics.
@ -289,6 +297,7 @@ void FTextureManager::AddGroup(const char * startlump, const char * endlump, int
{
CreateTexture (firsttx, usetype);
}
ST_Progress();
}
}
@ -344,6 +353,7 @@ void FTextureManager::AddHiresTextures ()
newtex->TopOffset = Scale(oldtex->TopOffset, newtex->ScaleY, 8);
ReplaceTexture(oldtexno, newtex, true);
}
ST_Progress();
}
}
}
@ -469,6 +479,7 @@ void FTextureManager::AddPatches (int lumpnum)
{
CreateTexture (Wads.CheckNumForName (name, ns_patches), FTexture::TEX_WallPatch);
}
ST_Progress();
}
delete file;
@ -718,8 +729,10 @@ DWORD R_BlendForColormap (DWORD map)
void R_InitData ()
{
FTexture::InitGrayMap();
ST_Progress();
TexMan.AddGroup("S_START", "S_END", ns_sprites, FTexture::TEX_Sprite);
R_InitPatches ();
R_InitPatches (); // Initializes "special" textures that have no external references
ST_Progress();
R_InitTextures ();
TexMan.AddGroup("F_START", "F_END", ns_flats, FTexture::TEX_Flat);
R_InitBuildTiles ();
@ -728,11 +741,121 @@ void R_InitData ()
TexMan.LoadHiresTex ();
TexMan.DefaultTexture = TexMan.CheckForTexture ("-NOFLAT-", FTexture::TEX_Override, 0);
V_InitFonts();
ST_Progress();
R_InitColormaps ();
C_InitConsole (SCREENWIDTH, SCREENHEIGHT, true);
ST_Progress();
}
//===========================================================================
//
// R_GuesstimateNumTextures
//
// Returns an estimate of the number of textures R_InitData will have to
// process. Used by D_DoomMain() when it calls ST_Init().
//
//===========================================================================
int R_GuesstimateNumTextures ()
{
int numtex;
numtex = R_CountGroup ("S_START", "S_END");
numtex += R_CountGroup ("F_START", "F_END");
numtex += R_CountGroup ("TX_START", "TX_END");
numtex += R_CountGroup ("HI_START", "HI_END");
numtex += R_CountBuildTiles ();
numtex += R_CountTexturesX ();
return numtex;
}
//===========================================================================
//
// R_CountGroup
//
//===========================================================================
static int R_CountGroup (const char *start, const char *end)
{
int startl = Wads.CheckNumForName (start);
int endl = Wads.CheckNumForName (end);
if (startl < 0 || endl < 0)
{
return 0;
}
else
{
return endl - startl - 1;
}
}
//===========================================================================
//
// R_CountTexturesX
//
// See R_InitTextures() for the logic in deciding what lumps to check.
//
//===========================================================================
static int R_CountTexturesX ()
{
int lastlump = 0, lump;
int texlump1 = -1, texlump2 = -1, texlump1a, texlump2a;
int count = 0;
int pfile = -1;
while ((lump = Wads.FindLump ("PNAMES", &lastlump)) != -1)
{
pfile = Wads.GetLumpFile (lump);
count += R_CountLumpTextures (lump);
texlump1 = Wads.CheckNumForName ("TEXTURE1", ns_global, pfile);
texlump2 = Wads.CheckNumForName ("TEXTURE2", ns_global, pfile);
count += R_CountLumpTextures (texlump1) - 1;
count += R_CountLumpTextures (texlump2) - 1;
}
texlump1a = Wads.CheckNumForName ("TEXTURE1");
texlump2a = Wads.CheckNumForName ("TEXTURE2");
if (texlump1a != -1 && (texlump1a == texlump1 || Wads.GetLumpFile (texlump1a) <= pfile))
{
texlump1a = -1;
}
if (texlump2a != -1 && (texlump2a == texlump2 || Wads.GetLumpFile (texlump2a) <= pfile))
{
texlump2a = -1;
}
count += R_CountLumpTextures (texlump1a) - 1;
count += R_CountLumpTextures (texlump2a) - 1;
return count;
}
//===========================================================================
//
// R_CountLumpTextures
//
// Returns the number of patches in a PNAMES/TEXTURE1/TEXTURE2 lump.
//
//===========================================================================
static int R_CountLumpTextures (int lumpnum)
{
if (lumpnum >= 0)
{
FWadLump file = Wads.OpenLumpNum (lumpnum);
DWORD numtex;
file >> numtex;
return numtex >= 0 ? numtex : 0;
}
return 0;
}
//===========================================================================
//
// R_DeinitData
//
//===========================================================================
void R_DeinitData ()
{
R_DeinitColormaps ();
@ -752,13 +875,15 @@ void R_DeinitData ()
free (drawsegs);
drawsegs = NULL;
}
}
//===========================================================================
//
// R_PrecacheLevel
//
// Preloads all relevant graphics for the level.
//
//===========================================================================
void R_PrecacheLevel (void)
{

View file

@ -782,8 +782,8 @@ void R_Init ()
R_SetViewSize (screenblocks);
R_InitPlanes ();
R_InitTranslationTables ();
R_InitParticles (); // [RH] Setup particle engine
R_InitColumnDrawers ();
colfunc = basecolfunc = R_DrawColumn;
fuzzcolfunc = R_DrawFuzzColumn;

View file

@ -195,7 +195,9 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, int x, int y, int wid
void R_ResetViewInterpolation ();
// Called by startup code.
int R_GuesstimateNumTextures ();
void R_Init (void);
void R_ExecuteSetViewSize (void);
// Called by M_Responder.
void R_SetViewSize (int blocks);

View file

@ -279,7 +279,6 @@ void S_Init ()
int i;
int curvelump;
Printf ("S_Init\n");
atterm (S_Shutdown);
// remove old data (S_Init can be called multiple times!)

View file

@ -49,7 +49,7 @@ EXTERN_CVAR (Float, vid_winscale)
IVideo *Video;
void I_ShutdownHardware ()
void I_ShutdownGraphics ()
{
if (screen)
delete screen, screen = NULL;
@ -57,7 +57,7 @@ void I_ShutdownHardware ()
delete Video, Video = NULL;
}
void I_InitHardware ()
void I_InitGraphics ()
{
UCVarValue val;
@ -68,7 +68,7 @@ void I_InitHardware ()
if (Video == NULL)
I_FatalError ("Failed to initialize display");
atterm (I_ShutdownHardware);
atterm (I_ShutdownGraphics);
Video->SetWindowedScale (vid_winscale);
}
@ -77,11 +77,6 @@ void I_InitHardware ()
// VIDEO WRAPPERS ---------------------------------------------------------
EDisplayType I_DisplayType ()
{
return Video->GetDisplayType ();
}
DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old)
{
bool fs = false;
@ -112,8 +107,7 @@ bool I_CheckResolution (int width, int height, int bits)
{
int twidth, theight;
Video->FullscreenChanged (screen ? screen->IsFullscreen() : fullscreen);
Video->StartModeIterator (bits);
Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen);
while (Video->NextMode (&twidth, &theight, NULL))
{
if (width == twidth && height == theight)
@ -129,10 +123,9 @@ void I_ClosestResolution (int *width, int *height, int bits)
int iteration;
DWORD closest = 4294967295u;
Video->FullscreenChanged (screen ? screen->IsFullscreen() : fullscreen);
for (iteration = 0; iteration < 2; iteration++)
{
Video->StartModeIterator (bits);
Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen);
while (Video->NextMode (&twidth, &theight, NULL))
{
if (twidth == *width && theight == *height)
@ -160,32 +153,14 @@ void I_ClosestResolution (int *width, int *height, int bits)
}
}
void I_StartModeIterator (int bits)
{
Video->StartModeIterator (bits);
}
bool I_NextMode (int *width, int *height, bool *letterbox)
{
return Video->NextMode (width, height, letterbox);
}
DCanvas *I_NewStaticCanvas (int width, int height)
{
return new DSimpleCanvas (width, height);
}
extern int NewWidth, NewHeight, NewBits, DisplayBits;
CUSTOM_CVAR (Bool, fullscreen, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
if (Video->FullscreenChanged (self))
{
NewWidth = screen->GetWidth();
NewHeight = screen->GetHeight();
NewBits = DisplayBits;
setmodeneeded = true;
}
NewWidth = screen->GetWidth();
NewHeight = screen->GetHeight();
NewBits = DisplayBits;
setmodeneeded = true;
}
CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -210,9 +185,13 @@ CCMD (vid_listmodes)
int width, height, bits;
bool letterbox;
if (Video == NULL)
{
return;
}
for (bits = 1; bits <= 32; bits++)
{
Video->StartModeIterator (bits);
Video->StartModeIterator (bits, screen->IsFullscreen());
while (Video->NextMode (&width, &height, &letterbox))
{
bool thisMode = (width == DisplayWidth && height == DisplayHeight && bits == DisplayBits);

View file

@ -47,47 +47,13 @@ class IVideo
virtual DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old) = 0;
virtual bool FullscreenChanged (bool fs) = 0;
virtual void StartModeIterator (int bits) = 0;
virtual void StartModeIterator (int bits, bool fs) = 0;
virtual bool NextMode (int *width, int *height, bool *letterbox) = 0;
};
class IInputDevice
{
public:
virtual ~IInputDevice () {}
virtual void ProcessInput (bool parm) = 0;
};
void I_InitGraphics ();
void I_ShutdownGraphics ();
class IKeyboard : public IInputDevice
{
public:
virtual void ProcessInput (bool consoleOpen) = 0;
virtual void SetKeypadRemapping (bool remap) = 0;
};
class IMouse : public IInputDevice
{
public:
virtual void SetGrabbed (bool grabbed) = 0;
virtual void ProcessInput (bool active) = 0;
};
class IJoystick : public IInputDevice
{
public:
enum EJoyProp
{
JOYPROP_SpeedMultiplier,
JOYPROP_XSensitivity,
JOYPROP_YSensitivity,
JOYPROP_XThreshold,
JOYPROP_YThreshold
};
virtual void SetProperty (EJoyProp prop, float val) = 0;
};
void I_InitHardware ();
void I_ShutdownHardware ();
extern IVideo *Video;
#endif // __HARDWARE_H__

View file

@ -226,7 +226,6 @@ void I_Init (void)
I_GetTime = I_GetTimePolled;
I_WaitForTic = I_WaitForTicPolled;
I_InitSound ();
I_InitHardware ();
}
void CalculateCPUSpeed ()
@ -329,18 +328,13 @@ void STACK_ARGS I_Error (const char *error, ...)
throw CRecoverableError (errortext);
}
char DoomStartupTitle[256] = { 0 };
void I_SetTitleString (const char *title)
void I_SetIWADInfo (const IWADInfo *info)
{
strcpy (DoomStartupTitle, title);
}
void I_PrintStr (const char *cp, bool scroll)
void I_PrintStr (const char *cp)
{
fputs (cp, stdout);
if (scroll)
putc ('\n', stdout);
fflush (stdout);
}
@ -356,7 +350,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad)
filepart = wads[i].Path;
else
filepart++;
printf ("%d. %s (%s)\n", i+1, IWADTypeNames[wads[i].Type], filepart);
printf ("%d. %s (%s)\n", i+1, IWADInfos[wads[i].Type].Name, filepart);
}
printf ("Which one? ");
scanf ("%d", &i);

View file

@ -179,10 +179,11 @@ void addterm (void (*func)(void), const char *name);
void popterm ();
// Print a console string
void I_PrintStr (const char *str, bool scroll);
void I_PrintStr (const char *str);
// Set the title string of the startup window
void I_SetTitleString (const char *title);
struct IWADInfo;
void I_SetIWADInfo (const IWADInfo *info);
// Pick from multiple IWADs to use
int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad);
@ -193,10 +194,6 @@ bool I_WriteIniFailed ();
// [RH] Returns millisecond-accurate time
unsigned int I_MSTime (void);
// [RH] Title string to display at bottom of console during startup
extern char DoomStartupTitle[256];
// Directory searching routines

View file

@ -46,9 +46,6 @@ bool I_CheckResolution (int width, int height, int bits);
void I_ClosestResolution (int *width, int *height, int bits);
bool I_SetResolution (int width, int height, int bits);
void I_StartModeIterator (int bits);
bool I_NextMode (int *width, int *height, bool letterbox);
bool I_AllocateScreen (DCanvas *canvas, int width, int height, int bits);
void I_FreeScreen (DCanvas *canvas);
@ -64,6 +61,4 @@ enum EDisplayType
DISPLAY_Both
};
EDisplayType I_DisplayType ();
#endif // __I_VIDEO_H__

View file

@ -140,17 +140,11 @@ SDLVideo::~SDLVideo ()
{
}
// This only changes how the iterator lists modes
bool SDLVideo::FullscreenChanged (bool fs)
{
IteratorFS = fs;
return true;
}
void SDLVideo::StartModeIterator (int bits)
void SDLVideo::StartModeIterator (int bits, bool fs)
{
IteratorMode = 0;
IteratorBits = bits;
IteratorFS = fs;
}
bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
@ -256,11 +250,6 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
fb = static_cast<SDLFB *>(CreateFrameBuffer (width, height, fullscreen, NULL));
}
if (fb->IsFullscreen() != fullscreen)
{
Video->FullscreenChanged (!fullscreen);
}
fb->SetFlash (flashColor, flashAmount);
return fb;

View file

@ -8,12 +8,11 @@ class SDLVideo : public IVideo
~SDLVideo ();
EDisplayType GetDisplayType () { return DISPLAY_Both; }
bool FullscreenChanged (bool fs);
void SetWindowedScale (float scale);
DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old);
void StartModeIterator (int bits);
void StartModeIterator (int bits, bool fs);
bool NextMode (int *width, int *height, bool *letterbox);
private:

165
src/sdl/st_start.cpp Normal file
View file

@ -0,0 +1,165 @@
/*
** st_start.cpp
** Handles the startup screen.
**
**---------------------------------------------------------------------------
** Copyright 2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <termios.h>
#include "st_start.h"
#include "doomdef.h"
termios OldTermIOS;
bool DidNetInit;
int NetProgressMax, NetProgressTicker;
char SpinnyProgressChars[8] = { '|', '/', '-', '\\', '|', '/', '-', '\\' };
void ST_Init(int maxProgress)
{
}
void ST_Done()
{
}
void ST_Progress()
{
}
void ST_NetInit(const char *message, int numplayers)
{
if (DidNetInit)
{
if (numplayers == 1)
{
// Status message without any real progress info.
printf ("\n%s.", message);
}
else
{
printf ("\n%s: ", message);
}
}
else
{
termios rawtermios;
printf ("Press 'Q' to abort network game synchronization.\n%s: ", message);
// Set stdin to raw mode so we can get keypresses in ST_CheckNetAbort()
// immediately without waiting for an EOL.
tcgetattr (STDIN_FILENO, &OldTermIOS);
rawtermios = OldTermIOS;
tcsetattr (STDIN_FILENO, &rawtermios);
}
NetProgressMax = numplayers;
NetProgressTicker = 0;
ST_NetProgress(); // You always know about yourself
}
void ST_NetDone()
{
// Restore stdin settings
tcsetattr (STDIN_FILENO, &OldTermIOS);
printf ("\n");
}
void ST_NetProgress(int count)
{
int i;
if (count == 0)
{
NetProgressTicker++;
}
else
{
NetProgressTicker = count;
}
if (NetProgressMax == 0)
{
// Spinny-type progress meter, because we're a guest.
printf ("%c\b", SpinnyProgressChars[NetProgressTicker & 7]);
}
else if (NetProgressMax > 1)
{
// Dotty-type progress meter, because we're a host.
printf (".%*c[%2d/%2d]", MAXPLAYERS + 1 - NetProgressTicker, NetProgressMax);
printf ("\b\b\b\b\b\b\b");
for (i = NetProgressTicker; i < MAXPLAYERS + 1; ++i)
{
printf ("\b");
}
}
}
bool ST_NetLoop(bool (*timer_callback)(void *), void *userdata)
{
fd_set rfds;
struct timeval tv;
int retval;
char k;
FD_ZERO (&rfds);
FD_SET (STDIN_FILENO, &rfds);
for (;;)
{
// Don't flood the network with packets on startup.
tv.tv_sec = 0;
tv.tv_usec = 250000;
retval = select (1, &rfds, NULL, NULL, &tv);
if (retval == -1)
{
// Error
}
else if (retval == 0)
{
if (timer_callback (userdata))
{
return true;
}
}
else if (read (STDIN_FILENO, &k, 1) == 1)
{
// Check input on stdin
if (k == 'q' || k == 'Q')
{
fprintf (stderr, "Network game synchronization aborted.");
return false;
}
}
}
}

View file

@ -151,27 +151,6 @@ CUSTOM_CVAR (Float, snd_sfxvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOI
}
#ifdef _WIN32
// [RH] Dialog procedure for the error dialog that appears if FMOD
// could not be initialized for some reason.
bool CALLBACK InitBoxCallback (HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
if (wParam == IDOK ||
wParam == IDC_NOSOUND ||
wParam == IDCANCEL)
{
EndDialog (hwndDlg, wParam);
return TRUE;
}
break;
}
return FALSE;
}
#endif
void I_InitSound ()
{
/* Get command line options: */
@ -215,23 +194,7 @@ void I_InitSound ()
{
delete GSnd;
GSnd = NULL;
#ifdef _WIN32
// If sound cannot be initialized, give the user some options.
switch (DialogBox (g_hInst,
MAKEINTRESOURCE(IDD_FMODINITFAILED),
(HWND)Window,
(DLGPROC)InitBoxCallback))
{
case IDC_NOSOUND:
break;
case IDCANCEL:
exit (0);
break;
}
#else
Printf ("Sound init failed. Using nosound.\n");
#endif
}
I_InitMusic ();
snd_sfxvolume.Callback ();

43
src/st_start.h Normal file
View file

@ -0,0 +1,43 @@
/*
** st_start.h
** Interface for the startup screen.
**
**---------------------------------------------------------------------------
** Copyright 2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
** The startup screen interface is based on a mix of Heretic and Hexen.
** Actual implementation is system-specific.
*/
extern void ST_Init(int maxProgress);
extern void ST_Done();
extern void ST_Progress();
extern void ST_NetInit(const char *message, int numplayers);
extern void ST_NetProgress(int count);
extern void ST_NetDone();
extern bool ST_NetLoop(bool (*timer_callback)(void *), void *userdata);

View file

@ -39,6 +39,7 @@
#include "w_wad.h"
#include "templates.h"
#include "cmdlib.h"
#include "st_start.h"
static TArray<BYTE *> BuildTileFiles;
@ -97,7 +98,13 @@ const BYTE *FBuildTexture::GetColumn (unsigned int column, const Span **spans_ou
return Pixels + column*Height;
}
//===========================================================================
//
// AddTiles
//
// Adds all the tiles in an artfile to the texture manager.
//
//===========================================================================
static void AddTiles (void *tiles)
{
@ -131,6 +138,7 @@ static void AddTiles (void *tiles)
tiledata++;
size--;
}
ST_Progress();
if ((picanm[pic] & 63) && (picanm[pic] & 192))
{
@ -194,17 +202,44 @@ static void AddTiles (void *tiles)
}
}
//===========================================================================
//
// R_InitBuildTiles
// CountTiles
//
// [RH] Support Build tiles!
// Returns the number of tiles provided by an artfile
//
//===========================================================================
void R_InitBuildTiles ()
static int CountTiles (void *tiles)
{
int version = LittleLong(*(DWORD *)tiles);
if (version != 1)
{
return 0;
}
int tilestart = LittleLong(((DWORD *)tiles)[2]);
int tileend = LittleLong(((DWORD *)tiles)[3]);
return tileend >= tilestart ? tileend - tilestart + 1 : 0;
}
//===========================================================================
//
// R_CountBuildTiles
//
// Returns the number of tiles found. Also loads all the data for
// R_InitBuildTiles() to process later.
//
//===========================================================================
int R_CountBuildTiles ()
{
int numartfiles = 0;
char artfile[] = "tilesXXX.art";
int lumpnum;
int numtiles;
int totaltiles = 0;
lumpnum = Wads.CheckNumForFullName ("blood.pal");
if (lumpnum >= 0)
@ -238,14 +273,14 @@ void R_InitBuildTiles ()
size_t len = Q_filelength (f);
BYTE *art = new BYTE[len];
if (fread (art, 1, len, f) != len || LittleLong(*(DWORD *)art) != 1)
if (fread (art, 1, len, f) != len || (numtiles = CountTiles(art)) == 0)
{
delete[] art;
}
else
{
BuildTileFiles.Push (art);
AddTiles (art);
totaltiles += numtiles;
}
fclose (f);
}
@ -265,18 +300,41 @@ void R_InitBuildTiles ()
BYTE *art = new BYTE[Wads.LumpLength (lumpnum)];
Wads.ReadLump (lumpnum, art);
if (LittleLong(*(DWORD *)art) != 1)
if ((numtiles = CountTiles(art)) == 0)
{
delete[] art;
}
else
{
BuildTileFiles.Push (art);
AddTiles (art);
totaltiles += numtiles;
}
}
return totaltiles;
}
//===========================================================================
//
// R_InitBuildTiles
//
// [RH] Support Build tiles!
//
//===========================================================================
void R_InitBuildTiles ()
{
for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i)
{
AddTiles (BuildTileFiles[i]);
}
}
//===========================================================================
//
// R_DeinitBuildTiles
//
//===========================================================================
void R_DeinitBuildTiles ()
{
for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i)
@ -285,4 +343,3 @@ void R_DeinitBuildTiles ()
}
BuildTileFiles.Clear();
}

View file

@ -39,6 +39,7 @@
#include "w_wad.h"
#include "i_system.h"
#include "gi.h"
#include "st_start.h"
// On the Alpha, accessing the shorts directly if they aren't aligned on a
// 4-byte boundary causes unaligned access warnings. Why it does this at
@ -511,6 +512,7 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int p
tex->UseType = FTexture::TEX_Null;
}
TexMan.AddTexture (tex);
ST_Progress();
}
}
}

View file

@ -1159,10 +1159,6 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
Decorations.Push (info);
MakeStateDefines(parent->ActorInfo->StateList);
info->NumOwnedStates = 0;
info->OwnedStates = NULL;
info->SpawnID = 0;
info->StateList = NULL;
ResetBaggage (bag);
bag->Info = info;

View file

@ -1862,5 +1862,4 @@ void V_InitFonts()
}
ConFont = new FSingleLumpFont ("ConsoleFont", Wads.GetNumForName ("CONFONT"));
V_InitCustomFonts ();
screen->SetFont(SmallFont);
}

View file

@ -58,10 +58,46 @@
#include "gi.h"
#include "templates.h"
#include "sbar.h"
#include "hardware.h"
IMPLEMENT_ABSTRACT_CLASS (DCanvas)
IMPLEMENT_ABSTRACT_CLASS (DFrameBuffer)
#if defined(_DEBUG) && defined(_M_IX86)
#define DBGBREAK { __asm int 3 }
#else
#define DBGBREAK
#endif
class DDummyFrameBuffer : public DFrameBuffer
{
DECLARE_CLASS (DDummyFrameBuffer, DFrameBuffer);
public:
DDummyFrameBuffer (int width, int height)
: DFrameBuffer (0, 0)
{
Width = width;
Height = height;
}
bool Lock(bool buffered) { DBGBREAK; return false; }
void Update() { DBGBREAK; }
PalEntry *GetPalette() { DBGBREAK; return NULL; }
void GetFlashedPalette(PalEntry palette[256]) { DBGBREAK; }
void UpdatePalette() { DBGBREAK; }
bool SetGamma(float gamma) { Gamma = gamma; return true; }
bool SetFlash(PalEntry rgb, int amount) { DBGBREAK; return false; }
void GetFlash(PalEntry &rgb, int &amount) { DBGBREAK; }
int GetPageCount() { DBGBREAK; return 0; }
bool IsFullscreen() { DBGBREAK; return 0; }
#ifdef _WIN32
void PaletteChanged() {}
int QueryNewPalette() { return 0; }
#endif
float Gamma;
};
IMPLEMENT_ABSTRACT_CLASS (DDummyFrameBuffer)
// SimpleCanvas is not really abstract, but this macro does not
// try to generate a CreateNew() function.
IMPLEMENT_ABSTRACT_CLASS (DSimpleCanvas)
@ -787,7 +823,6 @@ bool V_DoModeSetup (int width, int height, int bits)
DisplayHeight = height;
DisplayBits = bits;
R_InitColumnDrawers ();
R_MultiresInit ();
RenderTarget = screen;
@ -928,16 +963,37 @@ void V_Init (void)
bits = vid_defbits;
}
I_ClosestResolution (&width, &height, bits);
screen = new DDummyFrameBuffer (width, height);
if (!V_SetResolution (width, height, bits))
I_FatalError ("Could not set resolution to %d x %d x %d", width, height, bits);
BuildTransTable (GPalette.BaseColors);
}
void V_Init2()
{
assert (screen->IsKindOf(RUNTIME_CLASS(DDummyFrameBuffer)));
int width = screen->GetWidth();
int height = screen->GetHeight();
float gamma = static_cast<DDummyFrameBuffer *>(screen)->Gamma;
FFont *font = screen->Font;
delete screen;
screen = NULL;
I_InitGraphics();
I_ClosestResolution (&width, &height, 8);
if (!V_SetResolution (width, height, 8))
I_FatalError ("Could not set resolution to %d x %d x %d", width, height, 8);
else
Printf ("Resolution: %d x %d\n", SCREENWIDTH, SCREENHEIGHT);
screen->SetGamma (gamma);
screen->SetFont (font);
FBaseCVar::ResetColors ();
BuildTransTable (GPalette.BaseColors);
C_NewModeAdjust();
M_InitVideoModesMenu();
BorderNeedRefresh = screen->GetPageCount ();
setsizeneeded = true;
}
void V_Shutdown()

View file

@ -294,6 +294,9 @@ extern "C" DWORD *Col2RGB8_LessPrecision[65];
// Allocates buffer screens, call before R_Init.
void V_Init ();
// Initializes graphics mode for the first time.
void V_Init2 ();
void V_Shutdown ();
void V_MarkRect (int x, int y, int width, int height);

View file

@ -1691,7 +1691,7 @@ FWadLump FWadCollection::OpenLumpNum (int lump)
if ((unsigned)lump >= (unsigned)LumpInfo.Size())
{
I_Error ("W_MapLumpNum: %u >= NumLumps",lump);
I_Error ("W_OpenLumpNum: %u >= NumLumps", lump);
}
l = &LumpInfo[lump];
@ -1773,7 +1773,7 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
if ((unsigned)lump >= (unsigned)LumpInfo.Size())
{
I_Error ("W_MapLumpNum: %u >= NumLumps",lump);
I_Error ("W_ReopenLumpNum: %u >= NumLumps", lump);
}
l = &LumpInfo[lump];

View file

@ -55,6 +55,7 @@
#include "templates.h"
#include "i_system.h"
#include "i_video.h"
#include "i_input.h"
#include "v_video.h"
#include "v_pfx.h"
#include "stats.h"
@ -77,6 +78,8 @@ struct FBVERTEX
};
#define D3DFVF_FBVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX1)
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a);
@ -274,11 +277,11 @@ void D3DFB::FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, b
bool D3DFB::CreateResources ()
{
I_SetWndProc();
if (!Windowed)
{
// Remove the window border in fullscreen mode
SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU);
ShowWindow (Window, SW_SHOW);
SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE);
}
else
{
@ -305,7 +308,6 @@ bool D3DFB::CreateResources ()
SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER);
}
VidResizing = false;
ShowWindow (Window, SW_SHOWNORMAL);
}
if (FAILED(D3DDevice->CreatePixelShader (PalTexShaderDef, &PalTexShader)))
{

View file

@ -62,6 +62,8 @@
IMPLEMENT_CLASS(DDrawFB)
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a);
@ -228,11 +230,12 @@ bool DDrawFB::CreateResources ()
BufferCount = 1;
I_SetWndProc();
if (!Windowed)
{
ShowWindow (Window, SW_SHOW);
// Remove the window border in fullscreen mode
SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU);
SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE);
TrueHeight = Height;
for (Win32Video::ModeInfo *mode = static_cast<Win32Video *>(Video)->m_Modes; mode != NULL; mode = mode->next)
@ -313,7 +316,6 @@ bool DDrawFB::CreateResources ()
LOG1 ("SetWindowPos failed because %08lx\n", GetLastError());
}
VidResizing = false;
ShowWindow (Window, SW_SHOWNORMAL);
// Create the clipper
hr = DDraw->CreateClipper (0, &Clipper, NULL);

View file

@ -52,11 +52,8 @@ EXTERN_CVAR (Float, vid_winscale)
bool ForceWindowed;
IVideo *Video;
//static IKeyboard *Keyboard;
//static IMouse *Mouse;
//static IJoystick *Joystick;
void I_ShutdownHardware ()
void I_ShutdownGraphics ()
{
if (screen)
delete screen, screen = NULL;
@ -64,7 +61,7 @@ void I_ShutdownHardware ()
delete Video, Video = NULL;
}
void I_InitHardware ()
void I_InitGraphics ()
{
UCVarValue val;
@ -74,7 +71,7 @@ void I_InitHardware ()
if (Video == NULL)
I_FatalError ("Failed to initialize display");
atterm (I_ShutdownHardware);
atterm (I_ShutdownGraphics);
Video->SetWindowedScale (vid_winscale);
}
@ -83,11 +80,6 @@ void I_InitHardware ()
// VIDEO WRAPPERS ---------------------------------------------------------
EDisplayType I_DisplayType ()
{
return Video->GetDisplayType ();
}
DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old)
{
bool fs = false;
@ -125,8 +117,7 @@ bool I_CheckResolution (int width, int height, int bits)
{
int twidth, theight;
Video->FullscreenChanged (screen ? screen->IsFullscreen() : fullscreen);
Video->StartModeIterator (bits);
Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen);
while (Video->NextMode (&twidth, &theight, NULL))
{
if (width == twidth && height == theight)
@ -142,10 +133,9 @@ void I_ClosestResolution (int *width, int *height, int bits)
int iteration;
DWORD closest = 4294967295u;
Video->FullscreenChanged (screen ? screen->IsFullscreen() : fullscreen);
for (iteration = 0; iteration < 2; iteration++)
{
Video->StartModeIterator (bits);
Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen);
while (Video->NextMode (&twidth, &theight, NULL))
{
if (twidth == *width && theight == *height)
@ -173,32 +163,14 @@ void I_ClosestResolution (int *width, int *height, int bits)
}
}
void I_StartModeIterator (int bits)
{
Video->StartModeIterator (bits);
}
bool I_NextMode (int *width, int *height, bool *letterbox)
{
return Video->NextMode (width, height, letterbox);
}
DCanvas *I_NewStaticCanvas (int width, int height)
{
return new DSimpleCanvas (width, height);
}
extern int NewWidth, NewHeight, NewBits, DisplayBits;
CUSTOM_CVAR (Bool, fullscreen, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Bool, fullscreen, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
{
if (Video->FullscreenChanged (self))
{
NewWidth = screen->GetWidth();
NewHeight = screen->GetHeight();
NewBits = DisplayBits;
setmodeneeded = true;
}
NewWidth = screen->GetWidth();
NewHeight = screen->GetHeight();
NewBits = DisplayBits;
setmodeneeded = true;
}
CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -223,9 +195,14 @@ CCMD (vid_listmodes)
int width, height, bits;
bool letterbox;
if (Video == NULL)
{
return;
}
for (bits = 1; bits <= 32; bits++)
{
Video->StartModeIterator (bits);
Video->StartModeIterator (bits, screen->IsFullscreen());
while (Video->NextMode (&width, &height, &letterbox))
{
bool thisMode = (width == DisplayWidth && height == DisplayHeight && bits == DisplayBits);

View file

@ -47,47 +47,13 @@ class IVideo
virtual DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old) = 0;
virtual bool FullscreenChanged (bool fs) = 0;
virtual void StartModeIterator (int bits) = 0;
virtual void StartModeIterator (int bits, bool fs) = 0;
virtual bool NextMode (int *width, int *height, bool *letterbox) = 0;
};
class IInputDevice
{
public:
virtual ~IInputDevice () {}
virtual void ProcessInput (bool parm) = 0;
};
void I_InitGraphics ();
void I_ShutdownGraphics ();
class IKeyboard : public IInputDevice
{
public:
virtual void ProcessInput (bool consoleOpen) = 0;
virtual void SetKeypadRemapping (bool remap) = 0;
};
class IMouse : public IInputDevice
{
public:
virtual void SetGrabbed (bool grabbed) = 0;
virtual void ProcessInput (bool active) = 0;
};
class IJoystick : public IInputDevice
{
public:
enum EJoyProp
{
JOYPROP_SpeedMultiplier,
JOYPROP_XSensitivity,
JOYPROP_YSensitivity,
JOYPROP_XThreshold,
JOYPROP_YThreshold
};
virtual void SetProperty (EJoyProp prop, float val) = 0;
};
void I_InitHardware ();
void I_ShutdownHardware ();
extern IVideo *Video;
#endif // __HARDWARE_H__

View file

@ -198,7 +198,11 @@ bool FCDThread::Init ()
return false;
}
SetWindowLongPtr (CD_Window, GWL_USERDATA, (LONG)(LONG_PTR)this);
#ifdef _WIN64
SetWindowLongPtr (CD_Window, GWLP_USERDATA, (LONG_PTR)this);
#else
SetWindowLong (CD_Window, GWL_USERDATA, (LONG)(LONG_PTR)this);
#endif
SetThreadPriority (ThreadHandle, THREAD_PRIORITY_LOWEST);
return true;
}

View file

@ -1717,7 +1717,7 @@ static INT_PTR CALLBACK CrashDlgProc (HWND hDlg, UINT message, WPARAM wParam, LP
tcrect.right - tcrect.left - 8, tcrect.bottom - tcrect.top - tabrect.bottom - 8, 0);
tcitem.pszText = "Details";
tcitem.lParam = (LPARAM)CreateDialogParam (g_hInst, MAKEINTRESOURCE(IDD_CRASHDETAILS), hDlg, DetailsDlgProc, (LPARAM)edit);;
tcitem.lParam = (LPARAM)CreateDialogParam (g_hInst, MAKEINTRESOURCE(IDD_CRASHDETAILS), hDlg, DetailsDlgProc, (LPARAM)edit);
TabCtrl_InsertItem (edit, 1, &tcitem);
SetWindowPos ((HWND)tcitem.lParam, HWND_TOP, tcrect.left + 3, tcrect.top + tabrect.bottom + 3,
tcrect.right - tcrect.left - 8, tcrect.bottom - tcrect.top - tabrect.bottom - 8, 0);

View file

@ -116,7 +116,8 @@ extern bool SpawnEAXWindow;
static HMODULE DInputDLL;
static void KeyRead ();
static BOOL DI_Init2 ();
static BOOL I_StartupKeyboard ();
static void I_StartupMouse ();
static void MouseRead_DI ();
static void MouseRead_Win32 ();
static void GrabMouse_Win32 ();
@ -139,7 +140,7 @@ bool VidResizing;
extern bool SpawnEAXWindow;
extern BOOL vidactive;
extern HWND Window;
extern HWND Window, ConWindow;
extern HWND EAXEditWindow;
extern void UpdateJoystickMenu ();
@ -321,7 +322,7 @@ static FBaseCVar * const JoyConfigVars[] =
&joy_upspeed
};
CUSTOM_CVAR (Int, in_mouse, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Int, in_mouse, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
{
if (self < 0)
{
@ -337,22 +338,7 @@ CUSTOM_CVAR (Int, in_mouse, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
}
else
{
int new_mousemode;
if (self == 1 || (self == 0 && OSPlatform == os_WinNT4))
new_mousemode = win32;
else
new_mousemode = dinput;
if (new_mousemode != mousemode)
{
if (new_mousemode == win32)
I_GetWin32Mouse ();
else
if (!I_GetDIMouse ())
I_GetWin32Mouse ();
NativeMouse = false;
}
I_StartupMouse();
}
}
@ -512,6 +498,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
g_pKey->Acquire();
}
HaveFocus = true;
I_CheckNativeMouse (false);
break;
case WM_SIZE:
@ -1406,6 +1393,7 @@ bool I_InitInput (void *hwnd)
{
HRESULT hr;
Printf ("I_InitInput\n");
atterm (I_ShutdownInput);
NativeMouse = true;
@ -1478,7 +1466,15 @@ bool I_InitInput (void *hwnd)
}
}
DI_Init2();
Printf ("I_StartupMouse\n");
I_StartupMouse();
Printf ("I_StartupJoystick\n");
DI_EnumJoy ();
DI_InitJoy ();
Printf ("I_StartupKeyboard\n");
I_StartupKeyboard();
return TRUE;
}
@ -1559,6 +1555,24 @@ static void SetSoundPaused (int state)
static LONG PrevX, PrevY;
static void I_StartupMouse ()
{
int new_mousemode;
if (in_mouse == 1 || (in_mouse == 0 && OSPlatform == os_WinNT4))
new_mousemode = win32;
else
new_mousemode = dinput;
if (new_mousemode != mousemode)
{
if (new_mousemode == win32 || !I_GetDIMouse())
I_GetWin32Mouse ();
NativeMouse = false;
}
HaveFocus = GetFocus() == Window;
}
static void CenterMouse_Win32 (LONG curx, LONG cury)
{
RECT rect;
@ -1791,7 +1805,7 @@ static void MouseRead_DI ()
}
// Initialize the keyboard
static BOOL DI_Init2 (void)
static BOOL I_StartupKeyboard (void)
{
HRESULT hr;
@ -1827,9 +1841,6 @@ static BOOL DI_Init2 (void)
}
g_pKey->Acquire ();
DI_EnumJoy ();
DI_InitJoy ();
return TRUE;
}
@ -1840,6 +1851,11 @@ static void KeyRead ()
BYTE *fromState, *toState;
int i;
if (g_pKey == NULL)
{
return;
}
memset (&event, 0, sizeof(event));
fromState = DIKState[ActiveDIKState];
toState = DIKState[ActiveDIKState ^ 1];

View file

@ -23,7 +23,7 @@
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <mmsystem.h>
#include <objbase.h>
@ -57,14 +57,17 @@
#include "version.h"
#include "i_video.h"
#include "i_sound.h"
#include "i_input.h"
#include "autosegs.h"
#include "w_wad.h"
#include "templates.h"
#include "stats.h"
#include "st_start.h"
#include <assert.h>
#define WINDOW_TITLE GAMESIG " " DOTVERSIONSTR " (" __DATE__ ")"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
void CreateCrashLog (char *custominfo, DWORD customsize);
@ -80,16 +83,23 @@ extern EXCEPTION_POINTERS CrashPointers;
DArgs Args;
const char WinClassName[] = "ZDOOM WndClass";
const char ConClassName[] = "ZDOOM Logview";
const char WinClassName[] = "ZDoomMainWindow";
HINSTANCE g_hInst;
WNDCLASS WndClass;
HWND Window, ConWindow;
DWORD SessionID;
HANDLE MainThread;
DWORD MainThreadID;
// The main window
HWND Window;
// The subwindows used for startup and error output
HWND ConWindow, GameTitleWindow;
HWND ErrorPane, ProgressBar, NetStartPane;
HFONT GameTitleFont;
LONG GameTitleFontHeight;
HMODULE hwtsapi32; // handle to wtsapi32.dll
extern UINT TimerPeriod;
@ -99,6 +109,15 @@ extern HCURSOR TheArrowCursor, TheInvisibleCursor;
void (*TermFuncs[MAX_TERMS])(void);
static int NumTerms;
//===========================================================================
//
// atterm
//
// Our own atexit because atexit can be problematic under Linux, though I
// forget the circumstances that cause trouble.
//
//===========================================================================
void atterm (void (*func)(void))
{
// Make sure this function wasn't already registered.
@ -117,12 +136,26 @@ void atterm (void (*func)(void))
TermFuncs[NumTerms++] = func;
}
//===========================================================================
//
// popterm
//
// Removes the most recently register atterm function.
//
//===========================================================================
void popterm ()
{
if (NumTerms)
NumTerms--;
}
//===========================================================================
//
// call_terms
//
//===========================================================================
static void STACK_ARGS call_terms (void)
{
while (NumTerms > 0)
@ -139,11 +172,27 @@ static int STACK_ARGS NewFailure (size_t size)
}
#endif
//===========================================================================
//
// UnCOM
//
// Called by atterm if CoInitialize() succeeded.
//
//===========================================================================
static void UnCOM (void)
{
CoUninitialize ();
}
//===========================================================================
//
// UnWTS
//
// Called by atterm if RegisterSessionNotification() succeeded.
//
//===========================================================================
static void UnWTS (void)
{
if (hwtsapi32 != 0)
@ -159,49 +208,445 @@ static void UnWTS (void)
}
}
//===========================================================================
//
// LayoutErrorPane
//
// Lays out the error pane to the desired width, returning the required
// height.
//
//===========================================================================
static int LayoutErrorPane (HWND pane, int w)
{
HWND ctl;
RECT margin, rectc;
int cxicon, cyicon;
const char *text;
int textheight, textwidth, padding;
// Determine margin sizes.
SetRect (&margin, 7, 7, 0, 0);
MapDialogRect (pane, &margin);
// Get size of icon.
cxicon = GetSystemMetrics (SM_CXICON);
cyicon = GetSystemMetrics (SM_CYICON);
// Determine size of text control.
text = (const char *)(LONG_PTR)GetWindowLongPtr (pane, DWLP_USER);
textwidth = w - margin.left*3 - cxicon;
textheight = 0;
if (text != NULL)
{
HWND ctl;
HDC dc;
HGDIOBJ oldfont;
int len;
ctl = GetDlgItem (pane, IDC_ERRORTEXT);
rectc.top = rectc.left = 0;
rectc.right = textwidth;
rectc.bottom = 0;
len = (int)strlen(text);
dc = GetDC (pane);
oldfont = SelectObject (dc, (HFONT)SendMessage (ctl, WM_GETFONT, 0, 0));
DrawText (dc, text, len, &rectc, DT_CALCRECT | DT_EDITCONTROL | DT_NOPREFIX | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP);
SelectObject (dc, oldfont);
ReleaseDC (pane, dc);
textheight = rectc.bottom;
}
// Fill the text box to the determined size. If it is shorter than the icon,
// center it vertically.
padding = MAX (cyicon - textheight, 0);
ctl = GetDlgItem (pane, IDC_ERRORTEXT);
MoveWindow (ctl, margin.left*2 + cxicon, margin.top + padding/2, textwidth, textheight, TRUE);
InvalidateRect (ctl, NULL, TRUE);
textheight += padding;
// Center the Okay button horizontally, just underneath the text box.
ctl = GetDlgItem (pane, IDOK);
GetClientRect (ctl, &rectc); // Find out how big it is.
MoveWindow (ctl, (w - rectc.right) / 2, margin.top*2 + textheight, rectc.right, rectc.bottom, TRUE);
InvalidateRect (ctl, NULL, TRUE);
// Return the needed height for this layout
return margin.top*3 + textheight + rectc.bottom;
}
//===========================================================================
//
// LayoutNetStartPane
//
// Lays out the network startup pane to the specified width, returning
// its required height.
//
//===========================================================================
int LayoutNetStartPane (HWND pane, int w)
{
HWND ctl;
RECT margin, rectc;
int staticheight, barheight;
// Determine margin sizes.
SetRect (&margin, 7, 7, 0, 0);
MapDialogRect (pane, &margin);
// Stick the message text in the upper left corner.
ctl = GetDlgItem (pane, IDC_NETSTARTMESSAGE);
GetClientRect (ctl, &rectc);
MoveWindow (ctl, margin.left, margin.top, rectc.right, rectc.bottom, TRUE);
// Stick the count text in the upper right corner.
ctl = GetDlgItem (pane, IDC_NETSTARTCOUNT);
GetClientRect (ctl, &rectc);
MoveWindow (ctl, w - rectc.right - margin.left, margin.top, rectc.right, rectc.bottom, TRUE);
staticheight = rectc.bottom;
// Stretch the progress bar to fill the entire width.
ctl = GetDlgItem (pane, IDC_NETSTARTPROGRESS);
barheight = GetSystemMetrics (SM_CYVSCROLL);
MoveWindow (ctl, margin.left, margin.top*2 + staticheight, w - margin.left*2, barheight, TRUE);
// Center the abort button underneath the progress bar.
ctl = GetDlgItem (pane, IDCANCEL);
GetClientRect (ctl, &rectc);
MoveWindow (ctl, (w - rectc.right) / 2, margin.top*3 + staticheight + barheight, rectc.right, rectc.bottom, TRUE);
return margin.top*4 + staticheight + barheight + rectc.bottom;
}
//===========================================================================
//
// LayoutMainWindow
//
// Lays out the main window with the game title and log controls and
// possibly the error pane and progress bar.
//
//===========================================================================
void LayoutMainWindow (HWND hWnd, HWND pane)
{
RECT rect;
int errorpaneheight = 0;
int bannerheight = 0;
int progressheight = 0;
int netpaneheight = 0;
int w, h;
GetClientRect (hWnd, &rect);
w = rect.right;
h = rect.bottom;
if (pane != NULL)
{
errorpaneheight = LayoutErrorPane (pane, w);
SetWindowPos (pane, HWND_TOP, 0, 0, w, errorpaneheight, 0);
}
if (DoomStartupInfo != NULL)
{
bannerheight = GameTitleFontHeight + 5;
MoveWindow (GameTitleWindow, 0, errorpaneheight, w, bannerheight, TRUE);
InvalidateRect (GameTitleWindow, NULL, FALSE);
}
if (ProgressBar != NULL)
{
// Base the height of the progress bar on the height of a scroll bar
// arrow, just as in the progress bar example.
progressheight = GetSystemMetrics (SM_CYVSCROLL);
MoveWindow (ProgressBar, 0, h - progressheight, w, progressheight, TRUE);
}
if (NetStartPane != NULL)
{
netpaneheight = LayoutNetStartPane (NetStartPane, w);
SetWindowPos (NetStartPane, HWND_TOP, 0, h - progressheight - netpaneheight, w, netpaneheight, SWP_SHOWWINDOW);
RECT foo;
GetClientRect (NetStartPane, &foo);
foo.bottom = foo.bottom;;
}
// The log window uses whatever space is left.
MoveWindow (ConWindow, 0, errorpaneheight + bannerheight, w,
h - bannerheight - errorpaneheight - progressheight - netpaneheight, TRUE);
}
//===========================================================================
//
// LConProc
//
// The main window's WndProc during startup. During gameplay, the WndProc
// in i_input.cpp is used instead.
//
//===========================================================================
LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPMINMAXINFO minmax;
HWND view;
HDC hdc;
HBRUSH hbr;
HGDIOBJ oldfont;
RECT rect;
int titlelen;
SIZE size;
LOGFONT lf;
TEXTMETRIC tm;
HINSTANCE inst = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
HFONT font;
DRAWITEMSTRUCT *drawitem;
switch (msg)
{
case WM_SIZE:
if (wParam != SIZE_MAXHIDE && wParam != SIZE_MAXSHOW)
{
MoveWindow ((HWND)(LONG_PTR)GetWindowLongPtr (hWnd, GWLP_USERDATA),
0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
}
return 0;
case WM_GETMINMAXINFO:
minmax = (LPMINMAXINFO)lParam;
minmax->ptMinTrackSize.x *= 10;
minmax->ptMinTrackSize.y *= 8;
break;
case WM_CREATE:
view = CreateWindow ("EDIT", NULL,
// Create game title static control
memset (&lf, 0, sizeof(lf));
hdc = GetDC (hWnd);
lf.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72);
lf.lfCharSet = ANSI_CHARSET;
lf.lfWeight = FW_BOLD;
lf.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
strcpy (lf.lfFaceName, "Trebuchet MS");
GameTitleFont = CreateFontIndirect (&lf);
font = GameTitleFont != NULL ? GameTitleFont : (HFONT)GetStockObject (DEFAULT_GUI_FONT);
oldfont = SelectObject (hdc, font);
GetTextMetrics (hdc, &tm);
SelectObject (hdc, oldfont);
ReleaseDC (hWnd, hdc);
GameTitleFontHeight = tm.tmHeight;
// Create log read-only edit control
view = CreateWindowEx (WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE, "EDIT", NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE,
ES_LEFT | ES_MULTILINE | WS_CLIPSIBLINGS,
0, 0, 0, 0,
hWnd, NULL, (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_HINSTANCE), NULL);
hWnd, NULL, inst, NULL);
if (view == NULL)
{
return -1;
}
SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)view);
SendMessage (view, WM_SETFONT, (WPARAM)GetStockObject (DEFAULT_GUI_FONT), FALSE);
SendMessage (view, EM_SETREADONLY, TRUE, 0);
SendMessage (view, EM_SETLIMITTEXT, 0, 0);
ConWindow = view;
view = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, 0, 0, 0, 0, hWnd, NULL, inst, NULL);
if (view == NULL)
{
return -1;
}
GameTitleWindow = view;
return 0;
case WM_SIZE:
if (wParam != SIZE_MAXHIDE && wParam != SIZE_MAXSHOW)
{
LayoutMainWindow (hWnd, ErrorPane);
}
return 0;
case WM_DRAWITEM:
if (DoomStartupInfo != NULL)
{
const PalEntry *c;
// Draw the game title strip at the top of the window.
drawitem = (LPDRAWITEMSTRUCT)lParam;
// Draw the background.
rect = drawitem->rcItem;
rect.bottom -= 1;
c = (const PalEntry *)&DoomStartupInfo->BkColor;
hbr = CreateSolidBrush (RGB(c->r,c->g,c->b));
FillRect (drawitem->hDC, &drawitem->rcItem, hbr);
DeleteObject (hbr);
// Calculate width of the title string.
SetTextAlign (drawitem->hDC, TA_TOP);
oldfont = SelectObject (drawitem->hDC, GameTitleFont != NULL ? GameTitleFont : (HFONT)GetStockObject (DEFAULT_GUI_FONT));
titlelen = (int)strlen (DoomStartupInfo->Name);
GetTextExtentPoint32 (drawitem->hDC, DoomStartupInfo->Name, titlelen, &size);
// Draw the title.
c = (const PalEntry *)&DoomStartupInfo->FgColor;
SetTextColor (drawitem->hDC, RGB(c->r,c->g,c->b));
SetBkMode (drawitem->hDC, TRANSPARENT);
TextOut (drawitem->hDC, rect.left + (rect.right - rect.left - size.cx) / 2, 2, DoomStartupInfo->Name, titlelen);
SelectObject (drawitem->hDC, oldfont);
return TRUE;
}
return FALSE;
case WM_CLOSE:
PostQuitMessage (0);
break;
case WM_CTLCOLORSTATIC:
return (LRESULT)GetStockObject (WHITE_BRUSH);
case WM_DESTROY:
if (GameTitleFont != NULL)
{
DeleteObject (GameTitleFont);
}
break;
}
return DefWindowProc (hWnd, msg, wParam, lParam);
}
//===========================================================================
//
// ErrorPaneProc
//
// DialogProc for the error pane.
//
//===========================================================================
INT_PTR CALLBACK ErrorPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND ctl;
switch (msg)
{
case WM_INITDIALOG:
SetWindowLongPtr (hDlg, DWLP_USER, lParam);
// Set the static control to the error text.
ctl = GetDlgItem (hDlg, IDC_ERRORTEXT);
SetWindowText (ctl, (LPCSTR)lParam);
// Set the icon to the system default error icon.
ctl = GetDlgItem (hDlg, IDC_ICONPIC);
SendMessage (ctl, STM_SETICON, (WPARAM)LoadIcon (NULL, IDI_ERROR), 0);
// Appear in the main window.
LayoutMainWindow (GetParent (hDlg), hDlg);
// Make sure the last line of output is visible in the log window.
SendMessage (ConWindow, EM_LINESCROLL, 0, SendMessage (ConWindow, EM_GETLINECOUNT, 0, 0) -
SendMessage (ConWindow, EM_GETFIRSTVISIBLELINE, 0, 0));
return TRUE;
case WM_COMMAND:
// There is only one button, and it's "Ok" and makes us quit.
if (HIWORD(wParam) == BN_CLICKED)
{
PostQuitMessage (0);
return TRUE;
}
break;
}
return FALSE;
}
//===========================================================================
//
// I_SetWndProc
//
// Sets the main WndProc, hides all the child windows, and starts up
// in-game input.
//
//===========================================================================
void I_SetWndProc()
{
if (GetWindowLongPtr (Window, GWLP_USERDATA) == 0)
{
SetWindowLongPtr (Window, GWLP_USERDATA, 1);
SetWindowLongPtr (Window, GWLP_WNDPROC, (WLONG_PTR)WndProc);
ShowWindow (ConWindow, SW_HIDE);
ShowWindow (GameTitleWindow, SW_HIDE);
I_InitInput (Window);
}
}
//===========================================================================
//
// RestoreConView
//
// Returns the main window to its startup state.
//
//===========================================================================
void RestoreConView()
{
// Make sure the window has a frame in case it was fullscreened.
SetWindowLongPtr (Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW);
if (GetWindowLong (Window, GWL_EXSTYLE) & WS_EX_TOPMOST)
{
SetWindowPos (Window, HWND_BOTTOM, 0, 0, 512, 384,
SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE);
SetWindowPos (Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE);
}
else
{
SetWindowPos (Window, NULL, 0, 0, 512, 384,
SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER);
}
SetWindowLongPtr (Window, GWLP_WNDPROC, (WLONG_PTR)LConProc);
ShowWindow (ConWindow, SW_SHOW);
ShowWindow (GameTitleWindow, SW_SHOW);
// Make sure the progress bar isn't visible.
ST_Done();
}
//===========================================================================
//
// ShowErrorPane
//
// Shows an error message, preferably in the main window, but it can
// use a normal message box too.
//
//===========================================================================
void ShowErrorPane(const char *text)
{
size_t len = strlen(text);
ErrorPane = CreateDialogParam (g_hInst, MAKEINTRESOURCE(IDD_ERRORPANE), Window, ErrorPaneProc, (LPARAM)text);
if (ErrorPane == NULL)
{
MessageBox (Window, text,
"ZDOOM Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
}
else
{
BOOL bRet;
MSG msg;
SetWindowText (Window, "Fatal Error - " WINDOW_TITLE);
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
MessageBox (Window, text,
"ZDOOM Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
return;
}
else if (!IsDialogMessage (ErrorPane, &msg))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
}
}
//===========================================================================
//
// DoMain
//
//===========================================================================
void DoMain (HINSTANCE hInstance)
{
LONG WinWidth, WinHeight;
int height, width;
int height, width, x, y;
RECT cRect;
TIMECAPS tc;
@ -286,16 +731,28 @@ void DoMain (HINSTANCE hInstance)
GetModuleFileName (NULL, progdir, 1024);
*(strrchr (progdir, '\\') + 1) = 0;
FixPathSeperator (progdir);
/*
height = GetSystemMetrics (SM_CYFIXEDFRAME) * 2 +
GetSystemMetrics (SM_CYCAPTION) + 12 * 32;
width = GetSystemMetrics (SM_CXFIXEDFRAME) * 2 + 8 * 78;
*/
width = 512;
height = 384;
DEVMODE displaysettings = { sizeof(displaysettings) };
EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &displaysettings);
x = (displaysettings.dmPelsWidth - width) / 2;
y = (displaysettings.dmPelsHeight - height) / 2;
#if _DEBUG
x = y = 0;
#endif
TheInvisibleCursor = LoadCursor (hInstance, MAKEINTRESOURCE(IDC_INVISIBLECURSOR));
TheArrowCursor = LoadCursor (NULL, IDC_ARROW);
WNDCLASS WndClass;
WndClass.style = 0;
WndClass.lpfnWndProc = WndProc;
WndClass.lpfnWndProc = LConProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
@ -310,10 +767,12 @@ void DoMain (HINSTANCE hInstance)
I_FatalError ("Could not register window class");
/* create window */
Window = CreateWindow((LPCTSTR)WinClassName,
(LPCTSTR) GAMESIG " " DOTVERSIONSTR " (" __DATE__ ")",
WS_OVERLAPPEDWINDOW,
0/*CW_USEDEFAULT*/, 1/*CW_USEDEFAULT*/, width, height,
Window = CreateWindowEx(
WS_EX_APPWINDOW,
(LPCTSTR)WinClassName,
(LPCTSTR)WINDOW_TITLE,
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
x, y, width, height,
(HWND) NULL,
(HMENU) NULL,
hInstance,
@ -322,20 +781,6 @@ void DoMain (HINSTANCE hInstance)
if (!Window)
I_FatalError ("Could not open window");
WndClass.lpfnWndProc = LConProc;
WndClass.lpszClassName = (LPCTSTR)ConClassName;
if (RegisterClass ((LPWNDCLASS)&WndClass))
{
ConWindow = CreateWindowEx (
WS_EX_PALETTEWINDOW & (~WS_EX_TOPMOST),
(LPCTSTR)ConClassName,
(LPCTSTR) "ZDoom Startup Viewer",
WS_OVERLAPPEDWINDOW/* | WS_VISIBLE*/,
CW_USEDEFAULT, CW_USEDEFAULT,
512, 384,
Window, NULL, hInstance, NULL);
}
if (kernel != 0)
{
typedef BOOL (WINAPI *pts)(DWORD, DWORD *);
@ -378,19 +823,24 @@ void DoMain (HINSTANCE hInstance)
}
catch (class CDoomError &error)
{
I_ShutdownHardware ();
SetWindowPos (Window, NULL, 0, 0, 0, 0, SWP_HIDEWINDOW);
if (ConWindow != NULL)
{
ShowWindow (ConWindow, SW_SHOW);
}
I_ShutdownGraphics ();
RestoreConView ();
if (error.GetMessage ())
MessageBox (Window, error.GetMessage(),
"ZDOOM Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
{
ShowErrorPane (error.GetMessage());
}
exit (-1);
}
}
//===========================================================================
//
// DoomSpecificInfo
//
// Called by the crash logger to get application-specific information.
//
//===========================================================================
void DoomSpecificInfo (char *buffer)
{
const char *arg;
@ -459,27 +909,52 @@ extern FILE *Logfile;
// To make this work with MinGW, you will need to use inline assembly
// because GCC offers no native support for Windows' SEH.
//===========================================================================
//
// SleepForever
//
//===========================================================================
void SleepForever ()
{
Sleep (INFINITE);
}
//===========================================================================
//
// ExitMessedUp
//
// An exception occurred while exiting, so don't do any standard processing.
// Just die.
//
//===========================================================================
LONG WINAPI ExitMessedUp (LPEXCEPTION_POINTERS foo)
{
// An exception occurred while exiting, so don't do any
// standard processing. Just die.
ExitProcess (1000);
}
//===========================================================================
//
// ExitFatally
//
//===========================================================================
void CALLBACK ExitFatally (ULONG_PTR dummy)
{
SetUnhandledExceptionFilter (ExitMessedUp);
I_ShutdownHardware ();
SetWindowPos (Window, NULL, 0, 0, 0, 0, SWP_HIDEWINDOW);
I_ShutdownGraphics ();
RestoreConView ();
DisplayCrashLog ();
exit (-1);
}
//===========================================================================
//
// CatchAllExceptions
//
//===========================================================================
LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info)
{
#ifdef _DEBUG
@ -514,6 +989,15 @@ LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info)
return EXCEPTION_CONTINUE_EXECUTION;
}
//===========================================================================
//
// infiniterecursion
//
// Debugging routine for testing the crash logger.
//
//===========================================================================
#ifdef _DEBUG
static void infiniterecursion(int foo)
{
if (foo)
@ -521,6 +1005,13 @@ static void infiniterecursion(int foo)
infiniterecursion(foo);
}
}
#endif
//===========================================================================
//
// WinMain
//
//===========================================================================
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int nCmdShow)
{
@ -584,8 +1075,19 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
return 0;
}
//===========================================================================
//
// CCMD crashout
//
// Debugging routine for testing the crash logger.
// Useless in a debug build, because that doesn't enable the crash logger.
//
//===========================================================================
#ifndef _DEBUG
#include "c_dispatch.h"
CCMD (crashout)
{
*(int *)0 = 0;
}
#endif

View file

@ -322,7 +322,7 @@ int I_PlayMovie (const char *name)
SetPriorityClass (GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
I_CheckNativeMouse (true);
SetWindowLongPtr (Window, GWL_WNDPROC, (LONG_PTR)MovieWndProc);
SetWindowLongPtr (Window, GWLP_WNDPROC, (LONG_PTR)MovieWndProc);
if (FAILED (control->Run ()))
{
@ -343,7 +343,7 @@ int I_PlayMovie (const char *name)
MOVIE_Played;
bomb4:
SetWindowLongPtr (Window, GWL_WNDPROC, (LONG_PTR)WndProc);
SetWindowLongPtr (Window, GWLP_WNDPROC, (LONG_PTR)WndProc);
SetPriorityClass (GetCurrentProcess(), INGAME_PRIORITY_CLASS);
bomb3:

View file

@ -76,7 +76,7 @@ extern "C"
CPUInfo CPU;
}
extern HWND Window, ConWindow;
extern HWND Window, ConWindow, GameTitleWindow;
extern HINSTANCE g_hInst;
UINT TimerPeriod;
@ -86,6 +86,8 @@ HANDLE NewTicArrived;
uint32 LanguageIDs[4];
void CalculateCPUSpeed ();
const IWADInfo *DoomStartupInfo;
int (*I_GetTime) (bool saveMS);
int (*I_WaitForTic) (int);
@ -264,13 +266,19 @@ void I_DetectOS (void)
break;
}
Printf ("OS: Windows %s %lu.%lu (Build %lu)\n",
osname,
info.dwMajorVersion, info.dwMinorVersion,
OSPlatform == os_Win95 ? info.dwBuildNumber & 0xffff : info.dwBuildNumber);
if (info.szCSDVersion[0])
if (OSPlatform == os_Win95)
{
Printf (" %s\n", info.szCSDVersion);
Printf ("OS: Windows %s %lu.%lu.%lu %s\n",
osname,
info.dwMajorVersion, info.dwMinorVersion,
info.dwBuildNumber & 0xffff, info.szCSDVersion);
}
else
{
Printf ("OS: Windows %s %lu.%lu (Build %lu)\n %s\n",
osname,
info.dwMajorVersion, info.dwMinorVersion,
info.dwBuildNumber, info.szCSDVersion);
}
if (OSPlatform == os_unknown)
@ -427,8 +435,6 @@ void I_Init (void)
atterm (I_ShutdownSound);
I_InitSound ();
I_InitInput (Window);
I_InitHardware ();
}
void CalculateCPUSpeed ()
@ -547,38 +553,38 @@ void STACK_ARGS I_Error (const char *error, ...)
throw CRecoverableError (errortext);
}
char DoomStartupTitle[256] = { 0 };
extern void LayoutMainWindow (HWND hWnd, HWND pane);
void I_SetTitleString (const char *title)
void I_SetIWADInfo (const IWADInfo *info)
{
int i;
DoomStartupInfo = info;
for (i = 0; title[i]; i++)
DoomStartupTitle[i] = title[i];
// Make the startup banner show itself
LayoutMainWindow (Window, NULL);
}
void I_PrintStr (const char *cp, bool lineBreak)
void I_PrintStr (const char *cp)
{
if (ConWindow == NULL)
return;
static bool newLine = true;
HWND edit = (HWND)(LONG_PTR)GetWindowLongPtr (ConWindow, GWLP_USERDATA);
HWND edit = ConWindow;
char buf[256];
int bpos = 0;
INTBOOL visible = GetWindowLongPtr (ConWindow, GWL_STYLE) & WS_VISIBLE;
int selstart, selend;
SendMessage (edit, EM_GETSEL, (WPARAM)&selstart, (LPARAM)&selend);
int maxsel, selstart, selend, numlines1, numlines2;
// SendMessage (edit, EM_SETSEL, (WPARAM)-1, 0);
SendMessage (edit, EM_SETSEL, INT_MAX, INT_MAX);
if (lineBreak && !newLine)
if (visible)
{
buf[0] = '\r';
buf[1] = '\n';
bpos = 2;
SendMessage (edit, WM_SETREDRAW, FALSE, 0);
}
numlines1 = SendMessage (edit, EM_GETLINECOUNT, 0, 0);
maxsel = SendMessage (edit, WM_GETTEXTLENGTH, 0, 0);
SendMessage (edit, EM_GETSEL, (WPARAM)&selstart, (LPARAM)&selend);
SendMessage (edit, EM_SETSEL, maxsel, maxsel);
while (*cp != 0)
{
if (*cp == 28)
@ -611,6 +617,16 @@ void I_PrintStr (const char *cp, bool lineBreak)
newLine = buf[bpos-1] == '\n';
}
SendMessage (edit, EM_SETSEL, selstart, selend);
numlines2 = SendMessage (edit, EM_GETLINECOUNT, 0, 0);
if (numlines2 > numlines1)
{
SendMessage (edit, EM_LINESCROLL, 0, numlines2 - numlines1);
}
if (visible)
{
SendMessage (edit, WM_SETREDRAW, TRUE, 0);
I_GetEvent ();
}
}
EXTERN_CVAR (Bool, queryiwad);
@ -664,7 +680,7 @@ BOOL CALLBACK IWADBoxCallback (HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
filepart = WadList[i].Path;
else
filepart++;
work.Format ("%s (%s)", IWADTypeNames[WadList[i].Type], filepart);
work.Format ("%s (%s)", IWADInfos[WadList[i].Type].Name, filepart);
SendMessage (ctrl, LB_ADDSTRING, 0, (LPARAM)work.GetChars());
SendMessage (ctrl, LB_SETITEMDATA, i, (LPARAM)i);
}

View file

@ -186,10 +186,11 @@ void popterm ();
void I_PaintConsole (void);
// Print a console string
void I_PrintStr (const char *cp, bool lineBreak);
void I_PrintStr (const char *cp);
// Set the title string of the startup window
void I_SetTitleString (const char *title);
struct IWADInfo;
void I_SetIWADInfo (const IWADInfo *title);
// Pick from multiple IWADs to use
int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad);
@ -200,9 +201,20 @@ bool I_WriteIniFailed ();
// [RH] Returns millisecond-accurate time
unsigned int I_MSTime (void);
// [RH] Title string to display at bottom of console during startup
extern char DoomStartupTitle[256];
// [RH] Title banner to display during startup
extern const IWADInfo *DoomStartupInfo;
// [RH] Used by the display code to set the normal window procedure
void I_SetWndProc();
// Damn Microsoft for doing Get/SetWindowLongPtr half-assed. Instead of
// giving them proper prototypes under Win32, they are just macros for
// Get/SetWindowLong, meaning they take LONGs and not LONG_PTRs.
#ifdef _WIN64
typedef long long WLONG_PTR;
#else
typedef _W64 long WLONG_PTR;
#endif
// Directory searching routines

View file

@ -6,7 +6,6 @@
#define IDNO2 9
#define IDI_ICON1 101
#define IDD_MIDASINITERROR 108
#define IDD_FMODINITFAILED 111
#define IDD_IWADDIALOG 112
#define IDC_INVISIBLECURSOR 114
#define IDD_CRASHDIALOG 122
@ -31,7 +30,8 @@
#define IDI_BOING8 144
#define IDD_BOING 145
#define IDD_CRASHOVERVIEW 147
#define IDC_NOSOUND 1000
#define IDD_ERRORPANE 148
#define IDD_NETSTARTPANE 149
#define IDC_ERRORMESSAGE 1004
#define IDQUIT 1005
#define IDC_IWADLIST 1006
@ -92,6 +92,13 @@
#define IDC_CRASHTAB 1074
#define IDC_RICHEDIT23 1075
#define IDC_CRASHSUMMARY 1075
#define IDC_ERRORTEXT 1076
#define IDC_ICONPIC 1077
#define IDC_DIVIDERBAR 1078
#define IDC_PROGRESS1 1079
#define IDC_NETSTARTPROGRESS 1079
#define IDC_NETSTARTMESSAGE 1080
#define IDC_NETSTARTCOUNT 1081
#define IDCE_ENVIRONMENTDIFFUSION 1085
#define IDCS_ENVIRONMENTDIFFUSION 1086
#define IDCE_ROOM 1087
@ -149,9 +156,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 148
#define _APS_NEXT_RESOURCE_VALUE 150
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1076
#define _APS_NEXT_CONTROL_VALUE 1082
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

257
src/win32/st_start.cpp Normal file
View file

@ -0,0 +1,257 @@
/*
** st_start.cpp
** Handles the startup screen.
**
**---------------------------------------------------------------------------
** Copyright 2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#define USE_WINDOWS_DWORD
#include "st_start.h"
#include "resource.h"
#include "templates.h"
#include "i_system.h"
extern HINSTANCE g_hInst;
extern HWND Window, ConWindow, ProgressBar, NetStartPane;
extern void LayoutMainWindow (HWND hWnd, HWND pane);
INT_PTR CALLBACK NetStartPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
int MaxPos, CurPos;
int NetMaxPos, NetCurPos;
LRESULT NetMarqueeMode;
void ST_Init(int maxProgress)
{
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,maxProgress));
LayoutMainWindow (Window, NULL);
MaxPos = maxProgress;
CurPos = 0;
}
void ST_Done()
{
if (ProgressBar != NULL)
{
DestroyWindow (ProgressBar);
ProgressBar = NULL;
LayoutMainWindow (Window, NULL);
}
}
void ST_Progress()
{
if (CurPos < MaxPos)
{
CurPos++;
SendMessage (ProgressBar, PBM_SETPOS, CurPos, 0);
}
}
//===========================================================================
//
// ST_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
// is a scrolling marquee style. If numplayers is 1, then the progress bar
// is just a full bar. If numplayers is >= 2, then the progress bar is a
// normal one, and a progress count is also shown in the pane.
//
//===========================================================================
void ST_NetInit(const char *message, int numplayers)
{
NetMaxPos = numplayers;
if (NetStartPane == NULL)
{
NetStartPane = CreateDialogParam (g_hInst, MAKEINTRESOURCE(IDD_NETSTARTPANE), Window, NetStartPaneProc, 0);
// We don't need two progress bars.
if (ProgressBar != NULL)
{
DestroyWindow (ProgressBar);
ProgressBar = NULL;
}
LayoutMainWindow (Window, NULL);
// Make sure the last line of output is visible in the log window.
SendMessage (ConWindow, EM_LINESCROLL, 0, SendMessage (ConWindow, EM_GETLINECOUNT, 0, 0) -
SendMessage (ConWindow, EM_GETFIRSTVISIBLELINE, 0, 0));
}
if (NetStartPane != NULL)
{
HWND ctl;
SetDlgItemText (NetStartPane, IDC_NETSTARTMESSAGE, message);
ctl = GetDlgItem (NetStartPane, IDC_NETSTARTPROGRESS);
if (numplayers == 0)
{
// PBM_SETMARQUEE is only available under XP and above, so this might fail.
NetMarqueeMode = SendMessage (ctl, PBM_SETMARQUEE, TRUE, 100);
if (NetMarqueeMode == FALSE)
{
SendMessage (ctl, PBM_SETRANGE, 0, MAKELPARAM(0,16));
}
else
{
// If we don't set the PBS_MARQUEE style, then the marquee will never show up.
SetWindowLong (ctl, GWL_STYLE, GetWindowLong (ctl, GWL_STYLE) | PBS_MARQUEE);
}
SetDlgItemText (NetStartPane, IDC_NETSTARTCOUNT, "");
}
else
{
NetMarqueeMode = FALSE;
SendMessage (ctl, PBM_SETMARQUEE, FALSE, 0);
// Make sure the marquee really is turned off.
SetWindowLong (ctl, GWL_STYLE, GetWindowLong (ctl, GWL_STYLE) & (~PBS_MARQUEE));
SendMessage (ctl, PBM_SETRANGE, 0, MAKELPARAM(0,numplayers));
if (numplayers == 1)
{
SendMessage (ctl, PBM_SETPOS, 1, 0);
SetDlgItemText (NetStartPane, IDC_NETSTARTCOUNT, "");
}
}
}
NetMaxPos = numplayers;
NetCurPos = 0;
ST_NetProgress(1); // You always know about yourself
}
void ST_NetDone()
{
if (NetStartPane != NULL)
{
DestroyWindow (NetStartPane);
NetStartPane = NULL;
LayoutMainWindow (Window, NULL);
}
}
void ST_NetProgress(int count)
{
if (count == 0)
{
NetCurPos++;
}
else
{
NetCurPos = count;
}
if (NetStartPane == NULL)
{
return;
}
if (NetMaxPos == 0 && !NetMarqueeMode)
{
// PBM_SETMARQUEE didn't work, so just increment the progress bar endlessly.
SendDlgItemMessage (NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, NetCurPos & 15, 0);
}
else if (NetMaxPos > 1)
{
char buf[16];
sprintf (buf, "%d/%d", NetCurPos, NetMaxPos);
SetDlgItemText (NetStartPane, IDC_NETSTARTCOUNT, buf);
SendDlgItemMessage (NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, MIN(NetCurPos, NetMaxPos), 0);
}
}
//===========================================================================
//
// ST_NetLoop
//
// The timer_callback function is called approximately four times per second
// and passed the userdata value. It should return true to stop the loop and
// return control to the caller or false to continue the loop.
//
// ST_NetLoop will return true if the loop was halted by the callback and
// false if the loop was halted because the user wants to abort the
// network synchronization.
//
//===========================================================================
bool ST_NetLoop(bool (*timer_callback)(void *), void *userdata)
{
BOOL bRet;
MSG msg;
if (SetTimer (Window, 1337, 250, NULL) == 0)
{
I_FatalError ("Could not set network synchronization timer.");
}
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
KillTimer (Window, 1337);
return false;
}
else
{
if (msg.message == WM_TIMER && msg.hwnd == Window && msg.wParam == 1337)
{
if (timer_callback (userdata))
{
KillTimer (NetStartPane, 1);
return true;
}
}
if (!IsDialogMessage (NetStartPane, &msg))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
}
KillTimer (Window, 1337);
return false;
}
INT_PTR CALLBACK NetStartPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED)
{
PostQuitMessage (0);
return TRUE;
}
return FALSE;
}

View file

@ -58,12 +58,11 @@ class Win32Video : public IVideo
void InitDDraw();
EDisplayType GetDisplayType () { return DISPLAY_Both; }
bool FullscreenChanged (bool fs);
void SetWindowedScale (float scale);
DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old);
void StartModeIterator (int bits);
void StartModeIterator (int bits, bool fs);
bool NextMode (int *width, int *height, bool *letterbox);
bool GoFullscreen (bool yes);

View file

@ -135,8 +135,6 @@ Win32Video::~Win32Video ()
D3D = NULL;
}
ShowWindow (Window, SW_HIDE);
STOPLOG;
}
@ -396,18 +394,11 @@ void Win32Video::FreeModes ()
m_Modes = NULL;
}
// This only changes how the iterator lists modes
bool Win32Video::FullscreenChanged (bool fs)
{
LOG1 ("FS-changed: %d\n", fs);
m_IteratorFS = fs;
return true;
}
void Win32Video::StartModeIterator (int bits)
void Win32Video::StartModeIterator (int bits, bool fs)
{
m_IteratorMode = m_Modes;
m_IteratorBits = bits;
m_IteratorFS = fs;
}
bool Win32Video::NextMode (int *width, int *height, bool *letterbox)
@ -529,11 +520,6 @@ DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscr
}
retry = 0;
if (fb->IsFullscreen() != fullscreen)
{
Video->FullscreenChanged (!fullscreen);
}
fb->SetFlash (flashColor, flashAmount);
return fb;

View file

@ -82,7 +82,7 @@ BEGIN
" BEGIN\r\n"
" VALUE ""Translation"", 0x409, 1200\r\n"
" END\r\n"
"END\r\n"
"END\r\0"
END
#endif // APSTUDIO_INVOKED
@ -113,14 +113,6 @@ IDI_BOING8 ICON "boing8.ico"
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_FMODINITFAILED, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 55
END
IDD_IWADDIALOG, DIALOG
BEGIN
LEFTMARGIN, 5
@ -199,6 +191,22 @@ BEGIN
VERTGUIDE, 33
TOPMARGIN, 7
END
IDD_ERRORPANE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 183
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
IDD_NETSTARTPANE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 182
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
END
#endif // APSTUDIO_INVOKED
@ -208,18 +216,6 @@ END
// Dialog
//
IDD_FMODINITFAILED DIALOGEX 0, 0, 186, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "ZDoom Sound Initialization Failure"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "Retry",IDOK,129,7,50,14,WS_GROUP
PUSHBUTTON "No Sound",IDC_NOSOUND,129,24,50,14,WS_GROUP
PUSHBUTTON "Quit",IDCANCEL,129,41,50,14,WS_GROUP
LTEXT "Could not initialize sound. If the sound hardware is in use, stop the other program that is making sound and click Retry. Alternatively, click No Sound to play without sound.",IDC_STATIC,7,7,116,42
END
IDD_IWADDIALOG DIALOGEX 0, 0, 212, 186
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
@ -428,6 +424,26 @@ BEGIN
CONTROL "",IDC_BOINGPROGRESS,"msctls_progress32",NOT WS_VISIBLE | WS_BORDER | 0x1,33,22,147,9
END
IDD_ERRORPANE DIALOGEX 0, 0, 190, 55
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
EXSTYLE WS_EX_CONTROLPARENT | WS_EX_STATICEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,67,34,50,14
ICON "",IDC_ICONPIC,7,7,21,20
LTEXT "Static",IDC_ERRORTEXT,38,7,145,20,SS_NOPREFIX | 0x2000
END
IDD_NETSTARTPANE DIALOGEX 0, 0, 189, 55
STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Abort Network Game",IDCANCEL,45,34,89,14
CONTROL "",IDC_NETSTARTMESSAGE,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,7,7,116,8
CONTROL "",IDC_NETSTARTCOUNT,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,153,7,29,8,WS_EX_RIGHT
CONTROL "",IDC_NETSTARTPROGRESS,"msctls_progress32",WS_BORDER,7,18,175,10
END
/////////////////////////////////////////////////////////////////////////////
//

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="updaterevision"
ProjectGUID="{6077B7D6-349F-4077-B552-3BC302EF5859}"
RootNamespace="updaterevision"
@ -95,6 +95,82 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
@ -172,82 +248,6 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"

View file

@ -4693,6 +4693,10 @@
RelativePath=".\src\skins.h"
>
</File>
<File
RelativePath=".\src\st_start.h"
>
</File>
<File
RelativePath=".\src\st_stuff.h"
>
@ -5338,6 +5342,10 @@
RelativePath=".\src\win32\resource.h"
>
</File>
<File
RelativePath=".\src\win32\st_start.cpp"
>
</File>
<File
RelativePath=".\src\win32\win32iface.h"
>
@ -9875,6 +9883,50 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\sdl\st_start.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
</File>
</Filter>
</Files>
<Globals>