2008-01-27 11:25:03 +00:00
|
|
|
/*
|
|
|
|
** i_main.cpp
|
|
|
|
** System-specific startup code. Eventually calls D_DoomMain.
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
** Copyright 1998-2007 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.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
|
|
|
// HEADER FILES ------------------------------------------------------------
|
|
|
|
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#define _WIN32_WINNT 0x0501
|
|
|
|
#include <windows.h>
|
|
|
|
#include <mmsystem.h>
|
|
|
|
#include <objbase.h>
|
|
|
|
#include <commctrl.h>
|
|
|
|
#include <richedit.h>
|
|
|
|
|
|
|
|
//#include <wtsapi32.h>
|
|
|
|
#define NOTIFY_FOR_THIS_SESSION 0
|
|
|
|
|
|
|
|
#include <malloc.h>
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#include <eh.h>
|
|
|
|
#include <new.h>
|
|
|
|
#include <crtdbg.h>
|
|
|
|
#endif
|
|
|
|
#include "resource.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#define USE_WINDOWS_DWORD
|
|
|
|
#include "doomerrors.h"
|
|
|
|
#include "hardware.h"
|
|
|
|
|
|
|
|
#include "doomtype.h"
|
|
|
|
#include "m_argv.h"
|
|
|
|
#include "d_main.h"
|
|
|
|
#include "i_system.h"
|
|
|
|
#include "c_console.h"
|
|
|
|
#include "version.h"
|
|
|
|
#include "i_video.h"
|
|
|
|
#include "i_sound.h"
|
|
|
|
#include "i_input.h"
|
|
|
|
#include "w_wad.h"
|
|
|
|
#include "templates.h"
|
2008-09-15 23:47:00 +00:00
|
|
|
#include "cmdlib.h"
|
|
|
|
#include "g_level.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "r_main.h"
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
#include "stats.h"
|
|
|
|
#include "st_start.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
// MACROS ------------------------------------------------------------------
|
|
|
|
|
|
|
|
// The main window's title.
|
2008-05-01 21:45:22 +00:00
|
|
|
#ifdef _M_X64
|
|
|
|
#define X64 " 64-bit"
|
|
|
|
#else
|
|
|
|
#define X64 ""
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define WINDOW_TITLE GAMESIG " " DOTVERSIONSTR X64 " (" __DATE__ ")"
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
// The maximum number of functions that can be registered with atterm.
|
2008-07-04 16:54:29 +00:00
|
|
|
#define MAX_TERMS 64
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
// TYPES -------------------------------------------------------------------
|
|
|
|
|
|
|
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
|
|
|
|
|
|
|
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
|
|
|
|
void CreateCrashLog (char *custominfo, DWORD customsize);
|
|
|
|
void DisplayCrashLog ();
|
|
|
|
extern BYTE *ST_Util_BitsForBitmap (BITMAPINFO *bitmap_info);
|
|
|
|
|
|
|
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
|
|
|
|
|
|
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
|
|
|
|
|
|
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
|
|
|
|
|
|
|
extern EXCEPTION_POINTERS CrashPointers;
|
|
|
|
extern BITMAPINFO *StartupBitmap;
|
|
|
|
extern UINT TimerPeriod;
|
|
|
|
extern HCURSOR TheArrowCursor, TheInvisibleCursor;
|
|
|
|
|
|
|
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
|
|
|
|
|
|
|
// The command line arguments.
|
2008-03-12 15:21:17 +00:00
|
|
|
DArgs *Args;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
HINSTANCE g_hInst;
|
|
|
|
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, StartupScreen, ErrorIcon;
|
|
|
|
|
|
|
|
HFONT GameTitleFont;
|
|
|
|
LONG GameTitleFontHeight;
|
|
|
|
LONG DefaultGUIFontHeight;
|
|
|
|
LONG ErrorIconChar;
|
|
|
|
|
|
|
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
|
|
|
|
|
|
|
static const char WinClassName[] = "ZDoomMainWindow";
|
|
|
|
static HMODULE hwtsapi32; // handle to wtsapi32.dll
|
|
|
|
static void (*TermFuncs[MAX_TERMS])(void);
|
|
|
|
static int NumTerms;
|
|
|
|
|
|
|
|
// CODE --------------------------------------------------------------------
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
for (int i = 0; i < NumTerms; ++i)
|
|
|
|
{
|
|
|
|
if (TermFuncs[i] == func)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NumTerms == MAX_TERMS)
|
|
|
|
{
|
|
|
|
func ();
|
|
|
|
I_FatalError ("Too many exit functions registered.\nIncrease MAX_TERMS in i_main.cpp");
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
TermFuncs[--NumTerms]();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
static int STACK_ARGS NewFailure (size_t size)
|
|
|
|
{
|
|
|
|
I_FatalError ("Failed to allocate %d bytes from process heap", size);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#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)
|
|
|
|
{
|
|
|
|
typedef BOOL (WINAPI *ursn)(HWND);
|
|
|
|
ursn unreg = (ursn)GetProcAddress (hwtsapi32, "WTSUnRegisterSessionNotification");
|
|
|
|
if (unreg != 0)
|
|
|
|
{
|
|
|
|
unreg (Window);
|
|
|
|
}
|
|
|
|
FreeLibrary (hwtsapi32);
|
|
|
|
hwtsapi32 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
- Update to ZDoom r858:
- Added FMOD_OPENONLY to the callback version of CreateStream() to prevent it
from doing prebuffering of the song. This was causing the Linux version to
hang while waiting for input from the pipe, since Timidity hadn't been
started yet. I tried using a select call in the FillStream() method, but it
always seems to return the pipe as having nothing available. Unfortunately,
the game still falls all over itself if Timidity isn't available. Instead
of execvp failing nicely, X errors kill the game. I don't know why it's
doing that. My advice for Linux music: Skip Timidity++ and get a DLS patch
set (/WINDOWS/system32/drivers/gm.dls is probably the most common by far)
and set the snd_midipatchset cvar to point to it. It's faster and also
sounds a whole lot better than the crappy freepats Ubuntu wants to install
with Timidity++ (thank goodness I have the official patches from a real
GUS so I don't need to use them).
- GCC fixes.
- Fixed: After starting new music the music volume has to be reset so that
the song's relative volume takes effect.
- Removed the arbitrary 1024 bytes limit when the file being played is a MIDI
file. I had a D_DM2TTL that's only 990 bytes.
- Restructured I_RegisterSong so that $mididevice works again and also supports
selecting FMOD.
- Added Jim' Linux fix.
- Added MartinHowe's fix for mugshot display in status bars.
- The garbage collector is now run one last time just before exiting the game.
- Removed movie volume from the sound menu and renamed some of the other
options to give the MIDI device name more room to display itself.
- Moved the midi device selection into the main sound menu.
- Added FMOD as MIDI device -1, to replace the MIDI mapper. This is still the
default device. By default, it uses exactly the same DLS instruments as the
Microsoft GS Wavetable Synth. If you have another set DLS level 1 patch set
you want to use, set the snd_midipatchset cvar to specify where it should
load the instruments from.
- Changed the ProduceMIDI function to store its output into a TArray<BYTE>.
An overloaded version wraps around it to continue to supply file-writing
support for external Timidity++ usage.
- Added an FMOD credits banner to comply with their non-commercial license.
- Reimplemented the snd_buffersize cvar for the FMOD Ex sound system. Rather
than a time in ms, this is now the length in samples of the DSP buffer.
Also added the snd_buffercount cvar to offer complete control over the
call to FMOD::System::setDSPBufferSize(). Note that with any snd_samplerate
below about 44kHz, you will need to set snd_buffersize to avoid long
latencies.
- Reimplemented the snd_output cvar for the FMOD Ex sound system.
- Changed snd_samplerate default to 0. This now means to use the default
sample rate.
- Made snd_output, snd_output_format, snd_speakermode, snd_resampler, and
snd_hrtf available through the menu.
- Split the HRTF effect selection into its own cvar: snd_hrtf.
- Removed 96000 Hz option from the menu. It's still available through the
cvar, if desired.
- Fixed: If Windows sound init failed, retry with DirectSound. (Apparently,
WASAPI doesn't work with more than two speakers and PCM-Float output at the
same time.)
- Fixed: Area sounds only played from the front speakers once you got within
the 2D panning area.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@79 b0f79afe-0144-0410-b225-9a4edf0717df
2008-03-27 18:31:46 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FinalGC
|
|
|
|
//
|
|
|
|
// If this doesn't free everything, the debug CRT will let us know.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static void FinalGC()
|
|
|
|
{
|
|
|
|
Args = NULL;
|
|
|
|
GC::FullGC();
|
|
|
|
}
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// LayoutErrorPane
|
|
|
|
//
|
|
|
|
// Lays out the error pane to the desired width, returning the required
|
|
|
|
// height.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static int LayoutErrorPane (HWND pane, int w)
|
|
|
|
{
|
|
|
|
HWND ctl;
|
|
|
|
RECT rectc;
|
|
|
|
|
|
|
|
// Right-align the Quit button.
|
|
|
|
ctl = GetDlgItem (pane, IDOK);
|
|
|
|
GetClientRect (ctl, &rectc); // Find out how big it is.
|
|
|
|
MoveWindow (ctl, w - rectc.right - 1, 1, rectc.right, rectc.bottom, TRUE);
|
|
|
|
InvalidateRect (ctl, NULL, TRUE);
|
|
|
|
|
|
|
|
// Return the needed height for this layout
|
|
|
|
return rectc.bottom + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// 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 leftside = 0;
|
|
|
|
int w, h;
|
|
|
|
|
|
|
|
GetClientRect (hWnd, &rect);
|
|
|
|
w = rect.right;
|
|
|
|
h = rect.bottom;
|
|
|
|
|
|
|
|
if (DoomStartupInfo != NULL && GameTitleWindow != NULL)
|
|
|
|
{
|
|
|
|
bannerheight = GameTitleFontHeight + 5;
|
|
|
|
MoveWindow (GameTitleWindow, 0, 0, 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);
|
|
|
|
}
|
|
|
|
if (pane != NULL)
|
|
|
|
{
|
|
|
|
errorpaneheight = LayoutErrorPane (pane, w);
|
|
|
|
SetWindowPos (pane, HWND_TOP, 0, h - progressheight - netpaneheight - errorpaneheight, w, errorpaneheight, 0);
|
|
|
|
}
|
|
|
|
if (ErrorIcon != NULL)
|
|
|
|
{
|
|
|
|
leftside = GetSystemMetrics (SM_CXICON) + 6;
|
|
|
|
MoveWindow (ErrorIcon, 0, bannerheight, leftside, h - bannerheight - errorpaneheight - progressheight - netpaneheight, TRUE);
|
|
|
|
}
|
|
|
|
// If there is a startup screen, it covers the log window
|
|
|
|
if (StartupScreen != NULL)
|
|
|
|
{
|
|
|
|
SetWindowPos (StartupScreen, HWND_TOP, leftside, bannerheight, w - leftside,
|
|
|
|
h - bannerheight - errorpaneheight - progressheight - netpaneheight, SWP_SHOWWINDOW);
|
|
|
|
InvalidateRect (StartupScreen, NULL, FALSE);
|
|
|
|
MoveWindow (ConWindow, 0, 0, 0, 0, TRUE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The log window uses whatever space is left.
|
|
|
|
MoveWindow (ConWindow, leftside, bannerheight, w - leftside,
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
DRAWITEMSTRUCT *drawitem;
|
|
|
|
CHARFORMAT2 format;
|
|
|
|
|
|
|
|
switch (msg)
|
|
|
|
{
|
|
|
|
case WM_CREATE:
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
oldfont = SelectObject (hdc, GetStockObject (DEFAULT_GUI_FONT));
|
|
|
|
GetTextMetrics (hdc, &tm);
|
|
|
|
DefaultGUIFontHeight = tm.tmHeight;
|
|
|
|
if (GameTitleFont == NULL)
|
|
|
|
{
|
|
|
|
GameTitleFontHeight = DefaultGUIFontHeight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SelectObject (hdc, GameTitleFont);
|
|
|
|
GetTextMetrics (hdc, &tm);
|
|
|
|
GameTitleFontHeight = tm.tmHeight;
|
|
|
|
}
|
|
|
|
SelectObject (hdc, oldfont);
|
|
|
|
|
|
|
|
// Create log read-only edit control
|
|
|
|
view = CreateWindowEx (WS_EX_NOPARENTNOTIFY, RICHEDIT_CLASS, NULL,
|
|
|
|
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
|
|
|
|
ES_LEFT | ES_MULTILINE | WS_CLIPSIBLINGS,
|
|
|
|
0, 0, 0, 0,
|
|
|
|
hWnd, NULL, inst, NULL);
|
|
|
|
HRESULT hr;
|
|
|
|
hr = GetLastError();
|
|
|
|
if (view == NULL)
|
|
|
|
{
|
|
|
|
ReleaseDC (hWnd, hdc);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
SendMessage (view, EM_SETREADONLY, TRUE, 0);
|
|
|
|
SendMessage (view, EM_EXLIMITTEXT, 0, 0x7FFFFFFE);
|
|
|
|
SendMessage (view, EM_SETBKGNDCOLOR, 0, RGB(70,70,70));
|
|
|
|
// Setup default font for the log.
|
|
|
|
//SendMessage (view, WM_SETFONT, (WPARAM)GetStockObject (DEFAULT_GUI_FONT), FALSE);
|
|
|
|
format.cbSize = sizeof(format);
|
|
|
|
format.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_SIZE;
|
|
|
|
format.dwEffects = 0;
|
|
|
|
format.yHeight = 200;
|
|
|
|
format.crTextColor = RGB(223,223,223);
|
|
|
|
format.bPitchAndFamily = FF_SWISS | VARIABLE_PITCH;
|
|
|
|
strcpy (format.szFaceName, "Bitstream Vera Sans"); // At least I have it. :p
|
|
|
|
SendMessage (view, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format);
|
|
|
|
|
|
|
|
ConWindow = view;
|
|
|
|
ReleaseDC (hWnd, hdc);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
SetWindowLong (view, GWL_ID, IDC_STATIC_TITLE);
|
|
|
|
GameTitleWindow = view;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_SIZE:
|
|
|
|
if (wParam != SIZE_MAXHIDE && wParam != SIZE_MAXSHOW)
|
|
|
|
{
|
|
|
|
LayoutMainWindow (hWnd, ErrorPane);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_DRAWITEM:
|
|
|
|
// Draw title banner.
|
|
|
|
if (wParam == IDC_STATIC_TITLE && 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;
|
|
|
|
}
|
|
|
|
// Draw startup screen
|
|
|
|
else if (wParam == IDC_STATIC_STARTUP)
|
|
|
|
{
|
|
|
|
if (StartupScreen != NULL)
|
|
|
|
{
|
|
|
|
drawitem = (LPDRAWITEMSTRUCT)lParam;
|
|
|
|
|
|
|
|
rect = drawitem->rcItem;
|
|
|
|
// Windows expects DIBs to be bottom-up but ours is top-down,
|
|
|
|
// so flip it vertically while drawing it.
|
|
|
|
StretchDIBits (drawitem->hDC, rect.left, rect.bottom - 1, rect.right - rect.left, rect.top - rect.bottom,
|
|
|
|
0, 0, StartupBitmap->bmiHeader.biWidth, StartupBitmap->bmiHeader.biHeight,
|
|
|
|
ST_Util_BitsForBitmap(StartupBitmap), StartupBitmap, DIB_RGB_COLORS, SRCCOPY);
|
|
|
|
|
|
|
|
// If the title banner is gone, then this is an ENDOOM screen, so draw a short prompt
|
|
|
|
// where the command prompt would have been in DOS.
|
|
|
|
if (GameTitleWindow == NULL)
|
|
|
|
{
|
|
|
|
static const char QuitText[] = "Press any key or click anywhere in the window to quit.";
|
|
|
|
|
|
|
|
SetTextColor (drawitem->hDC, RGB(240,240,240));
|
|
|
|
SetBkMode (drawitem->hDC, TRANSPARENT);
|
|
|
|
oldfont = SelectObject (drawitem->hDC, (HFONT)GetStockObject (DEFAULT_GUI_FONT));
|
|
|
|
TextOut (drawitem->hDC, 3, drawitem->rcItem.bottom - DefaultGUIFontHeight - 3, QuitText, countof(QuitText)-1);
|
|
|
|
SelectObject (drawitem->hDC, oldfont);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw stop icon.
|
|
|
|
else if (wParam == IDC_ICONPIC)
|
|
|
|
{
|
|
|
|
HICON icon;
|
|
|
|
POINTL char_pos;
|
|
|
|
drawitem = (LPDRAWITEMSTRUCT)lParam;
|
|
|
|
|
|
|
|
// This background color should match the edit control's.
|
|
|
|
hbr = CreateSolidBrush (RGB(70,70,70));
|
|
|
|
FillRect (drawitem->hDC, &drawitem->rcItem, hbr);
|
|
|
|
DeleteObject (hbr);
|
|
|
|
|
|
|
|
// Draw the icon aligned with the first line of error text.
|
|
|
|
SendMessage (ConWindow, EM_POSFROMCHAR, (WPARAM)&char_pos, ErrorIconChar);
|
|
|
|
icon = (HICON)LoadImage (0, IDI_ERROR, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
|
|
|
DrawIcon (drawitem->hDC, 6, char_pos.y, icon);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
case WM_COMMAND:
|
|
|
|
if (ErrorIcon != NULL && (HWND)lParam == ConWindow && HIWORD(wParam) == EN_UPDATE)
|
|
|
|
{
|
|
|
|
// Be sure to redraw the error icon if the edit control changes.
|
|
|
|
InvalidateRect (ErrorIcon, NULL, TRUE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_CLOSE:
|
|
|
|
PostQuitMessage (0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
switch (msg)
|
|
|
|
{
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
// Appear in the main window.
|
|
|
|
LayoutMainWindow (GetParent (hDlg), hDlg);
|
|
|
|
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);
|
|
|
|
I_ShutdownInput (); // Make sure the mouse pointer is available.
|
|
|
|
// Make sure the progress bar isn't visible.
|
|
|
|
if (StartScreen != NULL)
|
|
|
|
{
|
|
|
|
delete StartScreen;
|
|
|
|
StartScreen = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// ShowErrorPane
|
|
|
|
//
|
|
|
|
// Shows an error message, preferably in the main window, but it can
|
|
|
|
// use a normal message box too.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void ShowErrorPane(const char *text)
|
|
|
|
{
|
|
|
|
if (Window == NULL || ConWindow == NULL)
|
|
|
|
{
|
|
|
|
MessageBox (Window, text,
|
|
|
|
GAMESIG " Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetWindowText (Window, "Fatal Error - " WINDOW_TITLE);
|
|
|
|
if (StartScreen != NULL) // Ensure that the network pane is hidden.
|
|
|
|
{
|
|
|
|
StartScreen->NetDone();
|
|
|
|
}
|
|
|
|
ErrorIcon = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, 0, 0, 0, 0, Window, NULL, g_hInst, NULL);
|
|
|
|
if (ErrorIcon != NULL)
|
|
|
|
{
|
|
|
|
SetWindowLong (ErrorIcon, GWL_ID, IDC_ICONPIC);
|
|
|
|
}
|
|
|
|
ErrorPane = CreateDialogParam (g_hInst, MAKEINTRESOURCE(IDD_ERRORPANE), Window, ErrorPaneProc, (LONG_PTR)NULL);
|
|
|
|
|
|
|
|
CHARRANGE end;
|
|
|
|
CHARFORMAT2 oldformat, newformat;
|
|
|
|
PARAFORMAT2 paraformat;
|
|
|
|
|
|
|
|
// Append the error message to the log.
|
|
|
|
end.cpMax = end.cpMin = GetWindowTextLength (ConWindow);
|
|
|
|
SendMessage (ConWindow, EM_EXSETSEL, 0, (LPARAM)&end);
|
|
|
|
|
|
|
|
// Remember current charformat.
|
|
|
|
oldformat.cbSize = sizeof(oldformat);
|
|
|
|
SendMessage (ConWindow, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&oldformat);
|
|
|
|
|
|
|
|
// Use bigger font and standout colors.
|
|
|
|
newformat.cbSize = sizeof(newformat);
|
|
|
|
newformat.dwMask = CFM_BOLD | CFM_COLOR | CFM_SIZE;
|
|
|
|
newformat.dwEffects = CFE_BOLD;
|
|
|
|
newformat.yHeight = oldformat.yHeight * 5 / 4;
|
|
|
|
newformat.crTextColor = RGB(255,170,170);
|
|
|
|
SendMessage (ConWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&newformat);
|
|
|
|
|
|
|
|
// Indent the rest of the text to make the error message stand out a little more.
|
|
|
|
paraformat.cbSize = sizeof(paraformat);
|
|
|
|
paraformat.dwMask = PFM_STARTINDENT | PFM_OFFSETINDENT | PFM_RIGHTINDENT;
|
|
|
|
paraformat.dxStartIndent = paraformat.dxOffset = paraformat.dxRightIndent = 120;
|
|
|
|
SendMessage (ConWindow, EM_SETPARAFORMAT, 0, (LPARAM)¶format);
|
|
|
|
SendMessage (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"\n");
|
|
|
|
|
|
|
|
// Find out where the error lines start for the error icon display control.
|
|
|
|
SendMessage (ConWindow, EM_EXGETSEL, 0, (LPARAM)&end);
|
|
|
|
ErrorIconChar = end.cpMax;
|
|
|
|
|
2009-02-20 09:24:51 +00:00
|
|
|
// Now start adding the actual error message.
|
2008-01-27 11:25:03 +00:00
|
|
|
SendMessage (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"Execution could not continue.\n\n");
|
|
|
|
|
|
|
|
// Restore old charformat but with light yellow text.
|
|
|
|
oldformat.crTextColor = RGB(255,255,170);
|
|
|
|
SendMessage (ConWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&oldformat);
|
|
|
|
|
|
|
|
// Add the error text.
|
|
|
|
SendMessage (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)text);
|
|
|
|
|
|
|
|
// Make sure the error text is not scrolled below the window.
|
|
|
|
SendMessage (ConWindow, EM_LINESCROLL, 0, SendMessage (ConWindow, EM_GETLINECOUNT, 0, 0));
|
|
|
|
// The above line scrolled everything off the screen, so pretend to move the scroll
|
|
|
|
// bar thumb, which clamps to not show any extra lines if it doesn't need to.
|
|
|
|
SendMessage (ConWindow, EM_SCROLL, SB_PAGEDOWN, 0);
|
|
|
|
|
|
|
|
BOOL bRet;
|
|
|
|
MSG msg;
|
|
|
|
|
|
|
|
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
|
|
|
|
{
|
|
|
|
if (bRet == -1)
|
|
|
|
{
|
|
|
|
MessageBox (Window, text,
|
|
|
|
GAMESIG " 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, x, y;
|
|
|
|
RECT cRect;
|
|
|
|
TIMECAPS tc;
|
|
|
|
DEVMODE displaysettings;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
_set_new_handler (NewFailure);
|
|
|
|
#endif
|
|
|
|
|
2008-03-12 15:21:17 +00:00
|
|
|
Args = new DArgs(__argc, __argv);
|
- Update to ZDoom r858:
- Added FMOD_OPENONLY to the callback version of CreateStream() to prevent it
from doing prebuffering of the song. This was causing the Linux version to
hang while waiting for input from the pipe, since Timidity hadn't been
started yet. I tried using a select call in the FillStream() method, but it
always seems to return the pipe as having nothing available. Unfortunately,
the game still falls all over itself if Timidity isn't available. Instead
of execvp failing nicely, X errors kill the game. I don't know why it's
doing that. My advice for Linux music: Skip Timidity++ and get a DLS patch
set (/WINDOWS/system32/drivers/gm.dls is probably the most common by far)
and set the snd_midipatchset cvar to point to it. It's faster and also
sounds a whole lot better than the crappy freepats Ubuntu wants to install
with Timidity++ (thank goodness I have the official patches from a real
GUS so I don't need to use them).
- GCC fixes.
- Fixed: After starting new music the music volume has to be reset so that
the song's relative volume takes effect.
- Removed the arbitrary 1024 bytes limit when the file being played is a MIDI
file. I had a D_DM2TTL that's only 990 bytes.
- Restructured I_RegisterSong so that $mididevice works again and also supports
selecting FMOD.
- Added Jim' Linux fix.
- Added MartinHowe's fix for mugshot display in status bars.
- The garbage collector is now run one last time just before exiting the game.
- Removed movie volume from the sound menu and renamed some of the other
options to give the MIDI device name more room to display itself.
- Moved the midi device selection into the main sound menu.
- Added FMOD as MIDI device -1, to replace the MIDI mapper. This is still the
default device. By default, it uses exactly the same DLS instruments as the
Microsoft GS Wavetable Synth. If you have another set DLS level 1 patch set
you want to use, set the snd_midipatchset cvar to specify where it should
load the instruments from.
- Changed the ProduceMIDI function to store its output into a TArray<BYTE>.
An overloaded version wraps around it to continue to supply file-writing
support for external Timidity++ usage.
- Added an FMOD credits banner to comply with their non-commercial license.
- Reimplemented the snd_buffersize cvar for the FMOD Ex sound system. Rather
than a time in ms, this is now the length in samples of the DSP buffer.
Also added the snd_buffercount cvar to offer complete control over the
call to FMOD::System::setDSPBufferSize(). Note that with any snd_samplerate
below about 44kHz, you will need to set snd_buffersize to avoid long
latencies.
- Reimplemented the snd_output cvar for the FMOD Ex sound system.
- Changed snd_samplerate default to 0. This now means to use the default
sample rate.
- Made snd_output, snd_output_format, snd_speakermode, snd_resampler, and
snd_hrtf available through the menu.
- Split the HRTF effect selection into its own cvar: snd_hrtf.
- Removed 96000 Hz option from the menu. It's still available through the
cvar, if desired.
- Fixed: If Windows sound init failed, retry with DirectSound. (Apparently,
WASAPI doesn't work with more than two speakers and PCM-Float output at the
same time.)
- Fixed: Area sounds only played from the front speakers once you got within
the 2D panning area.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@79 b0f79afe-0144-0410-b225-9a4edf0717df
2008-03-27 18:31:46 +00:00
|
|
|
atterm(FinalGC);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
// Under XP, get our session ID so we can know when the user changes/locks sessions.
|
|
|
|
// Since we need to remain binary compatible with older versions of Windows, we
|
|
|
|
// need to extract the ProcessIdToSessionId function from kernel32.dll manually.
|
|
|
|
HMODULE kernel = GetModuleHandle ("kernel32.dll");
|
|
|
|
|
|
|
|
// Set the timer to be as accurate as possible
|
|
|
|
if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR)
|
|
|
|
TimerPeriod = 1; // Assume minimum resolution of 1 ms
|
|
|
|
else
|
|
|
|
TimerPeriod = tc.wPeriodMin;
|
|
|
|
|
|
|
|
timeBeginPeriod (TimerPeriod);
|
|
|
|
|
|
|
|
/*
|
|
|
|
killough 1/98:
|
|
|
|
|
|
|
|
This fixes some problems with exit handling
|
|
|
|
during abnormal situations.
|
|
|
|
|
|
|
|
The old code called I_Quit() to end program,
|
|
|
|
while now I_Quit() is installed as an exit
|
|
|
|
handler and exit() is called to exit, either
|
|
|
|
normally or abnormally.
|
|
|
|
*/
|
|
|
|
|
|
|
|
atexit (call_terms);
|
|
|
|
|
|
|
|
atterm (I_Quit);
|
|
|
|
|
|
|
|
// Figure out what directory the program resides in.
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
char *program;
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
if (_get_pgmptr(&program) != 0)
|
|
|
|
{
|
|
|
|
I_FatalError("Could not determine program location.");
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
char progbuff[1024];
|
|
|
|
GetModuleFileName(0, progbuff, sizeof(progbuff));
|
|
|
|
progbuff[1023] = '\0';
|
|
|
|
program = progbuff;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
progdir = program;
|
|
|
|
program = progdir.LockBuffer();
|
|
|
|
*(strrchr(program, '\\') + 1) = '\0';
|
|
|
|
FixPathSeperator(program);
|
|
|
|
progdir.Truncate((long)strlen(program));
|
|
|
|
progdir.UnlockBuffer();
|
2008-01-27 11:25:03 +00:00
|
|
|
/*
|
|
|
|
height = GetSystemMetrics (SM_CYFIXEDFRAME) * 2 +
|
|
|
|
GetSystemMetrics (SM_CYCAPTION) + 12 * 32;
|
|
|
|
width = GetSystemMetrics (SM_CXFIXEDFRAME) * 2 + 8 * 78;
|
|
|
|
*/
|
|
|
|
width = 512;
|
|
|
|
height = 384;
|
|
|
|
|
|
|
|
// Many Windows structures that specify their size do so with the first
|
|
|
|
// element. DEVMODE is not one of those structures.
|
|
|
|
memset (&displaysettings, 0, sizeof(displaysettings));
|
|
|
|
displaysettings.dmSize = sizeof(displaysettings);
|
|
|
|
EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &displaysettings);
|
|
|
|
x = (displaysettings.dmPelsWidth - width) / 2;
|
|
|
|
y = (displaysettings.dmPelsHeight - height) / 2;
|
|
|
|
|
2008-03-12 15:21:17 +00:00
|
|
|
if (Args->CheckParm ("-0"))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
x = y = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
TheInvisibleCursor = LoadCursor (hInstance, MAKEINTRESOURCE(IDC_INVISIBLECURSOR));
|
|
|
|
TheArrowCursor = LoadCursor (NULL, IDC_ARROW);
|
|
|
|
|
|
|
|
WNDCLASS WndClass;
|
|
|
|
WndClass.style = 0;
|
|
|
|
WndClass.lpfnWndProc = LConProc;
|
|
|
|
WndClass.cbClsExtra = 0;
|
|
|
|
WndClass.cbWndExtra = 0;
|
|
|
|
WndClass.hInstance = hInstance;
|
|
|
|
WndClass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1));
|
|
|
|
WndClass.hCursor = TheArrowCursor;
|
|
|
|
WndClass.hbrBackground = NULL;
|
|
|
|
WndClass.lpszMenuName = NULL;
|
|
|
|
WndClass.lpszClassName = (LPCTSTR)WinClassName;
|
|
|
|
|
|
|
|
/* register this new class with Windows */
|
|
|
|
if (!RegisterClass((LPWNDCLASS)&WndClass))
|
|
|
|
I_FatalError ("Could not register window class");
|
|
|
|
|
|
|
|
/* create window */
|
|
|
|
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,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (!Window)
|
|
|
|
I_FatalError ("Could not open window");
|
|
|
|
|
|
|
|
if (kernel != 0)
|
|
|
|
{
|
|
|
|
typedef BOOL (WINAPI *pts)(DWORD, DWORD *);
|
|
|
|
pts pidsid = (pts)GetProcAddress (kernel, "ProcessIdToSessionId");
|
|
|
|
if (pidsid != 0)
|
|
|
|
{
|
|
|
|
if (!pidsid (GetCurrentProcessId(), &SessionID))
|
|
|
|
{
|
|
|
|
SessionID = 0;
|
|
|
|
}
|
|
|
|
hwtsapi32 = LoadLibraryA ("wtsapi32.dll");
|
|
|
|
if (hwtsapi32 != 0)
|
|
|
|
{
|
|
|
|
FARPROC reg = GetProcAddress (hwtsapi32, "WTSRegisterSessionNotification");
|
|
|
|
if (reg == 0 || !((BOOL(WINAPI *)(HWND, DWORD))reg) (Window, NOTIFY_FOR_THIS_SESSION))
|
|
|
|
{
|
|
|
|
FreeLibrary (hwtsapi32);
|
|
|
|
hwtsapi32 = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
atterm (UnWTS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GetClientRect (Window, &cRect);
|
|
|
|
|
|
|
|
WinWidth = cRect.right;
|
|
|
|
WinHeight = cRect.bottom;
|
|
|
|
|
|
|
|
CoInitialize (NULL);
|
|
|
|
atterm (UnCOM);
|
|
|
|
|
|
|
|
C_InitConsole (((WinWidth / 8) + 2) * 8, (WinHeight / 12) * 8, false);
|
|
|
|
|
|
|
|
I_DetectOS ();
|
|
|
|
D_DoomMain ();
|
|
|
|
}
|
|
|
|
catch (class CDoomError &error)
|
|
|
|
{
|
|
|
|
I_ShutdownGraphics ();
|
|
|
|
RestoreConView ();
|
|
|
|
if (error.GetMessage ())
|
|
|
|
{
|
|
|
|
ShowErrorPane (error.GetMessage());
|
|
|
|
}
|
|
|
|
exit (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// DoomSpecificInfo
|
|
|
|
//
|
|
|
|
// Called by the crash logger to get application-specific information.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
void DoomSpecificInfo (char *buffer, size_t bufflen)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
const char *arg;
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
char *const buffend = buffer + bufflen - 2; // -2 for CRLF at end
|
2008-01-27 11:25:03 +00:00
|
|
|
int i;
|
|
|
|
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "ZDoom version " DOTVERSIONSTR " (" __DATE__ ")\r\n");
|
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\nCommand line: %s\r\n", GetCommandLine());
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
for (i = 0; (arg = Wads.GetWadName (i)) != NULL; ++i)
|
|
|
|
{
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\nWad %d: %s", i, arg);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gamestate != GS_LEVEL && gamestate != GS_TITLELEVEL)
|
|
|
|
{
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nNot in a level.");
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char name[9];
|
|
|
|
|
|
|
|
strncpy (name, level.mapname, 8);
|
|
|
|
name[8] = 0;
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nCurrent map: %s", name);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
if (!viewactive)
|
|
|
|
{
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nView not active.");
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nviewx = %d", viewx);
|
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewy = %d", viewy);
|
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewz = %d", viewz);
|
|
|
|
buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewangle = %x", viewangle);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
*buffer++ = '\r';
|
|
|
|
*buffer++ = '\n';
|
|
|
|
*buffer++ = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Here is how the error logging system works.
|
|
|
|
//
|
|
|
|
// To catch exceptions that occur in secondary threads, CatchAllExceptions is
|
|
|
|
// set as the UnhandledExceptionFilter for this process. It records the state
|
|
|
|
// of the thread at the time of the crash using CreateCrashLog and then queues
|
|
|
|
// an APC on the primary thread. When the APC executes, it raises a software
|
|
|
|
// exception that gets caught by the __try/__except block in WinMain.
|
|
|
|
// I_GetEvent calls SleepEx to put the primary thread in a waitable state
|
|
|
|
// periodically so that the APC has a chance to execute.
|
|
|
|
//
|
|
|
|
// Exceptions on the primary thread are caught by the __try/__except block in
|
|
|
|
// WinMain. Not only does it record the crash information, it also shuts
|
|
|
|
// everything down and displays a dialog with the information present. If a
|
|
|
|
// console log is being produced, the information will also be appended to it.
|
|
|
|
//
|
|
|
|
// If a debugger is running, CatchAllExceptions never executes, so secondary
|
|
|
|
// thread exceptions will always be caught by the debugger. For the primary
|
|
|
|
// thread, IsDebuggerPresent is called to determine if a debugger is present.
|
|
|
|
// Note that this function is not present on Windows 95, so we cannot
|
|
|
|
// statically link to it.
|
|
|
|
//
|
|
|
|
// 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)
|
|
|
|
{
|
|
|
|
ExitProcess (1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// ExitFatally
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void CALLBACK ExitFatally (ULONG_PTR dummy)
|
|
|
|
{
|
|
|
|
SetUnhandledExceptionFilter (ExitMessedUp);
|
|
|
|
I_ShutdownGraphics ();
|
|
|
|
RestoreConView ();
|
|
|
|
DisplayCrashLog ();
|
|
|
|
exit (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// CatchAllExceptions
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info)
|
|
|
|
{
|
|
|
|
#ifdef _DEBUG
|
|
|
|
if (info->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
|
|
|
|
{
|
|
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static bool caughtsomething = false;
|
|
|
|
|
|
|
|
if (caughtsomething) return EXCEPTION_EXECUTE_HANDLER;
|
|
|
|
caughtsomething = true;
|
|
|
|
|
|
|
|
char *custominfo = (char *)HeapAlloc (GetProcessHeap(), 0, 16384);
|
|
|
|
|
|
|
|
CrashPointers = *info;
|
Update to ZDoom r1083. Not fully tested yet!
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code.
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@138 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-23 18:35:55 +00:00
|
|
|
DoomSpecificInfo (custominfo, 16384);
|
2008-01-27 11:25:03 +00:00
|
|
|
CreateCrashLog (custominfo, (DWORD)strlen(custominfo));
|
|
|
|
|
|
|
|
// If the main thread crashed, then make it clean up after itself.
|
|
|
|
// Otherwise, put the crashing thread to sleep and signal the main thread to clean up.
|
|
|
|
if (GetCurrentThreadId() == MainThreadID)
|
|
|
|
{
|
2008-05-01 21:45:22 +00:00
|
|
|
#ifndef _M_X64
|
2008-01-27 11:25:03 +00:00
|
|
|
info->ContextRecord->Eip = (DWORD_PTR)ExitFatally;
|
2008-05-01 21:45:22 +00:00
|
|
|
#else
|
|
|
|
info->ContextRecord->Rip = (DWORD_PTR)ExitFatally;
|
|
|
|
#endif
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-05-01 21:45:22 +00:00
|
|
|
#ifndef _M_X64
|
2008-01-27 11:25:03 +00:00
|
|
|
info->ContextRecord->Eip = (DWORD_PTR)SleepForever;
|
2008-05-01 21:45:22 +00:00
|
|
|
#else
|
|
|
|
info->ContextRecord->Rip = (DWORD_PTR)SleepForever;
|
|
|
|
#endif
|
2008-01-27 11:25:03 +00:00
|
|
|
QueueUserAPC (ExitFatally, MainThread, 0);
|
|
|
|
}
|
|
|
|
return EXCEPTION_CONTINUE_EXECUTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// infiniterecursion
|
|
|
|
//
|
|
|
|
// Debugging routine for testing the crash logger.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
static void infiniterecursion(int foo)
|
|
|
|
{
|
|
|
|
if (foo)
|
|
|
|
{
|
|
|
|
infiniterecursion(foo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// WinMain
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int nCmdShow)
|
|
|
|
{
|
|
|
|
g_hInst = hInstance;
|
|
|
|
|
|
|
|
InitCommonControls (); // Load some needed controls and be pretty under XP
|
|
|
|
|
|
|
|
if (NULL == LoadLibrary ("riched20.dll"))
|
|
|
|
{
|
|
|
|
// Technically, it isn't really Internet Explorer that is needed, but this
|
|
|
|
// is an example of a specific program that will provide riched20.dll.
|
|
|
|
// But considering how much extra stuff needs to be installed to make Windows 95
|
|
|
|
// useable with pretty much any recent software, the chances are high that
|
|
|
|
// the user already has riched20.dll installed.
|
|
|
|
I_FatalError ("Sorry, you need to install Internet Explorer 3 or higher to play ZDoom on Windows 95.");
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(__GNUC__) && defined(_DEBUG)
|
|
|
|
if (__argc == 2 && strcmp (__argv[1], "TestCrash") == 0)
|
|
|
|
{
|
|
|
|
__try
|
|
|
|
{
|
|
|
|
*(int *)0 = 0;
|
|
|
|
}
|
|
|
|
__except(CrashPointers = *GetExceptionInformation(),
|
|
|
|
CreateCrashLog (__argv[1], 9), EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
DisplayCrashLog ();
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
if (__argc == 2 && strcmp (__argv[1], "TestStackCrash") == 0)
|
|
|
|
{
|
|
|
|
__try
|
|
|
|
{
|
|
|
|
infiniterecursion(1);
|
|
|
|
}
|
|
|
|
__except(CrashPointers = *GetExceptionInformation(),
|
|
|
|
CreateCrashLog (__argv[1], 14), EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
DisplayCrashLog ();
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
MainThread = INVALID_HANDLE_VALUE;
|
|
|
|
DuplicateHandle (GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &MainThread,
|
|
|
|
0, FALSE, DUPLICATE_SAME_ACCESS);
|
|
|
|
MainThreadID = GetCurrentThreadId();
|
|
|
|
|
|
|
|
#ifndef _DEBUG
|
|
|
|
if (MainThread != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
SetUnhandledExceptionFilter (CatchAllExceptions);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(_DEBUG) && defined(_MSC_VER)
|
|
|
|
// Uncomment this line to make the Visual C++ CRT check the heap before
|
|
|
|
// every allocation and deallocation. This will be slow, but it can be a
|
|
|
|
// great help in finding problem areas.
|
|
|
|
//_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
|
2008-06-08 09:24:55 +00:00
|
|
|
|
|
|
|
// Enable leak checking at exit.
|
2008-01-27 11:25:03 +00:00
|
|
|
_CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF);
|
2008-06-08 09:24:55 +00:00
|
|
|
|
|
|
|
// Use this to break at a specific allocation number.
|
|
|
|
//_crtBreakAlloc = 5501;
|
2008-01-27 11:25:03 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
DoMain (hInstance);
|
|
|
|
|
|
|
|
CloseHandle (MainThread);
|
|
|
|
MainThread = INVALID_HANDLE_VALUE;
|
|
|
|
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
|