mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- Added the -norun parameter to quit the game just before video
initialization. To be used to check for errors in scripts without actually running the game. - Added the -stdout parameter to the Windows version to send all output to a console, like the Linux version has done all along. SVN r1486 (trunk)
This commit is contained in:
parent
314216343d
commit
c2aab5dd46
5 changed files with 185 additions and 40 deletions
|
@ -1,4 +1,11 @@
|
|||
March 16, 2009
|
||||
March 17, 2009
|
||||
- Added the -norun parameter to quit the game just before video
|
||||
initialization. To be used to check for errors in scripts without actually
|
||||
running the game.
|
||||
- Added the -stdout parameter to the Windows version to send all output to
|
||||
a console, like the Linux version has done all along.
|
||||
|
||||
March 16, 2009
|
||||
- Added support for loading ZGL2 nodes. (Only useful with UDMF and maps with
|
||||
more than 65534 lines.)
|
||||
|
||||
|
|
|
@ -2637,6 +2637,12 @@ void D_DoomMain (void)
|
|||
|
||||
delete StartScreen;
|
||||
StartScreen = NULL;
|
||||
|
||||
if (Args->CheckParm("-norun"))
|
||||
{
|
||||
throw CNoRunExit();
|
||||
}
|
||||
|
||||
V_Init2();
|
||||
|
||||
files = Args->GatherFiles ("-playdemo", ".lmp", false);
|
||||
|
|
|
@ -68,6 +68,10 @@ private:
|
|||
char m_Message[MAX_ERRORTEXT];
|
||||
};
|
||||
|
||||
class CNoRunExit : public CDoomError
|
||||
{
|
||||
};
|
||||
|
||||
class CRecoverableError : public CDoomError
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -125,6 +125,8 @@ HINSTANCE g_hInst;
|
|||
DWORD SessionID;
|
||||
HANDLE MainThread;
|
||||
DWORD MainThreadID;
|
||||
HANDLE StdOut;
|
||||
bool FancyStdOut, AttachedStdOut;
|
||||
|
||||
// The main window
|
||||
HWND Window;
|
||||
|
@ -806,6 +808,49 @@ void DoMain (HINSTANCE hInstance)
|
|||
// need to extract the ProcessIdToSessionId function from kernel32.dll manually.
|
||||
HMODULE kernel = GetModuleHandle ("kernel32.dll");
|
||||
|
||||
if (Args->CheckParm("-stdout"))
|
||||
{
|
||||
// As a GUI application, we don't normally get a console when we start.
|
||||
// If we were run from the shell and are on XP+, we can attach to its
|
||||
// console. Otherwise, we can create a new one. If we already have a
|
||||
// stdout handle, then we have been redirected and should just use that
|
||||
// handle instead of creating a console window.
|
||||
|
||||
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (StdOut != NULL)
|
||||
{
|
||||
// It seems that running from a shell always creates a std output
|
||||
// for us, even if it doesn't go anywhere. (Running from Explorer
|
||||
// does not.) If we can get file information for this handle, it's
|
||||
// a file or pipe, so use it. Otherwise, pretend it wasn't there
|
||||
// and find a console to use instead.
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
if (!GetFileInformationByHandle(StdOut, &info))
|
||||
{
|
||||
StdOut = NULL;
|
||||
}
|
||||
}
|
||||
if (StdOut == NULL)
|
||||
{
|
||||
// AttachConsole was introduced with Windows XP. (OTOH, since we
|
||||
// have to share the console with the shell, I'm not sure if it's
|
||||
// a good idea to actually attach to it.)
|
||||
typedef BOOL (WINAPI *ac)(DWORD);
|
||||
ac attach_console = kernel != NULL ? (ac)GetProcAddress(kernel, "AttachConsole") : NULL;
|
||||
if (attach_console != NULL && attach_console(ATTACH_PARENT_PROCESS))
|
||||
{
|
||||
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD foo; WriteFile(StdOut, "\n", 1, &foo, NULL);
|
||||
AttachedStdOut = true;
|
||||
}
|
||||
if (StdOut == NULL && AllocConsole())
|
||||
{
|
||||
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
}
|
||||
FancyStdOut = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the timer to be as accurate as possible
|
||||
if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR)
|
||||
TimerPeriod = 1; // Assume minimum resolution of 1 ms
|
||||
|
@ -906,7 +951,7 @@ void DoMain (HINSTANCE hInstance)
|
|||
if (!Window)
|
||||
I_FatalError ("Could not open window");
|
||||
|
||||
if (kernel != 0)
|
||||
if (kernel != NULL)
|
||||
{
|
||||
typedef BOOL (WINAPI *pts)(DWORD, DWORD *);
|
||||
pts pidsid = (pts)GetProcAddress (kernel, "ProcessIdToSessionId");
|
||||
|
@ -946,6 +991,36 @@ void DoMain (HINSTANCE hInstance)
|
|||
I_DetectOS ();
|
||||
D_DoomMain ();
|
||||
}
|
||||
catch (class CNoRunExit &)
|
||||
{
|
||||
I_ShutdownGraphics();
|
||||
if (FancyStdOut && !AttachedStdOut)
|
||||
{ // Outputting to a new console window: Wait for a keypress before quitting.
|
||||
DWORD bytes;
|
||||
HANDLE stdinput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
ShowWindow (Window, SW_HIDE);
|
||||
WriteFile(StdOut, "Press any key to exit...", 24, &bytes, NULL);
|
||||
FlushConsoleInputBuffer(stdinput);
|
||||
SetConsoleMode(stdinput, 0);
|
||||
ReadConsole(stdinput, &bytes, 1, &bytes, NULL);
|
||||
}
|
||||
else if (StdOut == NULL)
|
||||
{
|
||||
BOOL bRet;
|
||||
MSG msg;
|
||||
|
||||
RestoreConView();
|
||||
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
|
||||
{
|
||||
if (bRet == -1)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
catch (class CDoomError &error)
|
||||
{
|
||||
I_ShutdownGraphics ();
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#include "v_font.h"
|
||||
#include "g_level.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
#include "v_palette.h"
|
||||
#include "stats.h"
|
||||
|
||||
EXTERN_CVAR (String, language)
|
||||
|
@ -74,6 +74,8 @@ EXTERN_CVAR (String, language)
|
|||
extern void CheckCPUID(CPUInfo *cpu);
|
||||
|
||||
extern HWND Window, ConWindow, GameTitleWindow;
|
||||
extern HANDLE StdOut;
|
||||
extern bool FancyStdOut;
|
||||
extern HINSTANCE g_hInst;
|
||||
|
||||
double PerfToSec, PerfToMillisec;
|
||||
|
@ -554,10 +556,9 @@ void I_SetIWADInfo (const IWADInfo *info)
|
|||
|
||||
void I_PrintStr (const char *cp)
|
||||
{
|
||||
if (ConWindow == NULL)
|
||||
if (ConWindow == NULL && StdOut == NULL)
|
||||
return;
|
||||
|
||||
static bool newLine = true;
|
||||
HWND edit = ConWindow;
|
||||
char buf[256];
|
||||
int bpos = 0;
|
||||
|
@ -566,17 +567,20 @@ void I_PrintStr (const char *cp)
|
|||
LONG lines_before, lines_after;
|
||||
CHARFORMAT format;
|
||||
|
||||
// Store the current selection and set it to the end so we can append text.
|
||||
SendMessage (edit, EM_EXGETSEL, 0, (LPARAM)&selection);
|
||||
endselection.cpMax = endselection.cpMin = GetWindowTextLength (edit);
|
||||
SendMessage (edit, EM_EXSETSEL, 0, (LPARAM)&endselection);
|
||||
if (edit != NULL)
|
||||
{
|
||||
// Store the current selection and set it to the end so we can append text.
|
||||
SendMessage (edit, EM_EXGETSEL, 0, (LPARAM)&selection);
|
||||
endselection.cpMax = endselection.cpMin = GetWindowTextLength (edit);
|
||||
SendMessage (edit, EM_EXSETSEL, 0, (LPARAM)&endselection);
|
||||
|
||||
// GetWindowTextLength and EM_EXSETSEL can disagree on where the end of
|
||||
// the text is. Find out what EM_EXSETSEL thought it was and use that later.
|
||||
SendMessage (edit, EM_EXGETSEL, 0, (LPARAM)&endselection);
|
||||
// GetWindowTextLength and EM_EXSETSEL can disagree on where the end of
|
||||
// the text is. Find out what EM_EXSETSEL thought it was and use that later.
|
||||
SendMessage (edit, EM_EXGETSEL, 0, (LPARAM)&endselection);
|
||||
|
||||
// Remember how many lines there were before we added text.
|
||||
lines_before = SendMessage (edit, EM_GETLINECOUNT, 0, 0);
|
||||
// Remember how many lines there were before we added text.
|
||||
lines_before = SendMessage (edit, EM_GETLINECOUNT, 0, 0);
|
||||
}
|
||||
|
||||
while (*cp != 0)
|
||||
{
|
||||
|
@ -584,8 +588,15 @@ void I_PrintStr (const char *cp)
|
|||
if ((*cp == 28 && bpos != 0) || bpos == 255)
|
||||
{
|
||||
buf[bpos] = 0;
|
||||
SendMessage (edit, EM_REPLACESEL, FALSE, (LPARAM)buf);
|
||||
newLine = buf[bpos-1] == '\n';
|
||||
if (edit != NULL)
|
||||
{
|
||||
SendMessage (edit, EM_REPLACESEL, FALSE, (LPARAM)buf);
|
||||
}
|
||||
if (StdOut != NULL)
|
||||
{
|
||||
DWORD bytes_written;
|
||||
WriteFile(StdOut, buf, bpos, &bytes_written, NULL);
|
||||
}
|
||||
bpos = 0;
|
||||
}
|
||||
if (*cp != 28)
|
||||
|
@ -602,39 +613,81 @@ void I_PrintStr (const char *cp)
|
|||
{
|
||||
// Change the color of future text added to the control.
|
||||
PalEntry color = V_LogColorFromColorRange (range);
|
||||
// GDI uses BGR colors, but color is RGB, so swap the R and the B.
|
||||
swap (color.r, color.b);
|
||||
// Change the color.
|
||||
format.cbSize = sizeof(format);
|
||||
format.dwMask = CFM_COLOR;
|
||||
format.dwEffects = 0;
|
||||
format.crTextColor = color;
|
||||
SendMessage (edit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);
|
||||
if (StdOut != NULL && FancyStdOut)
|
||||
{
|
||||
// Unfortunately, we are pretty limited here: There are only
|
||||
// eight basic colors, and each comes in a dark and a bright
|
||||
// variety.
|
||||
float h, s, v, r, g, b;
|
||||
WORD attrib = 0;
|
||||
|
||||
RGBtoHSV(color.r / 255.0, color.g / 255.0, color.b / 255.0, &h, &s, &v);
|
||||
if (s != 0)
|
||||
{ // color
|
||||
HSVtoRGB(&r, &g, &b, h, 1, 1);
|
||||
if (r == 1) attrib = FOREGROUND_RED;
|
||||
if (g == 1) attrib |= FOREGROUND_GREEN;
|
||||
if (b == 1) attrib |= FOREGROUND_BLUE;
|
||||
if (v > 0.6) attrib |= FOREGROUND_INTENSITY;
|
||||
}
|
||||
else
|
||||
{ // gray
|
||||
if (v < 0.33) attrib = FOREGROUND_INTENSITY;
|
||||
else if (v < 0.90) attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
|
||||
else attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
||||
}
|
||||
SetConsoleTextAttribute(StdOut, attrib);
|
||||
}
|
||||
if (edit != NULL)
|
||||
{
|
||||
// GDI uses BGR colors, but color is RGB, so swap the R and the B.
|
||||
swap (color.r, color.b);
|
||||
// Change the color.
|
||||
format.cbSize = sizeof(format);
|
||||
format.dwMask = CFM_COLOR;
|
||||
format.dwEffects = 0;
|
||||
format.crTextColor = color;
|
||||
SendMessage (edit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bpos != 0)
|
||||
{
|
||||
buf[bpos] = 0;
|
||||
SendMessage (edit, EM_REPLACESEL, FALSE, (LPARAM)buf);
|
||||
newLine = buf[bpos-1] == '\n';
|
||||
}
|
||||
|
||||
// If the old selection was at the end of the text, keep it at the end and
|
||||
// scroll. Don't scroll if the selection is anywhere else.
|
||||
if (selection.cpMin == endselection.cpMin && selection.cpMax == endselection.cpMax)
|
||||
{
|
||||
selection.cpMax = selection.cpMin = GetWindowTextLength (edit);
|
||||
lines_after = SendMessage (edit, EM_GETLINECOUNT, 0, 0);
|
||||
if (lines_after > lines_before)
|
||||
if (edit != NULL)
|
||||
{
|
||||
SendMessage (edit, EM_LINESCROLL, 0, lines_after - lines_before);
|
||||
SendMessage (edit, EM_REPLACESEL, FALSE, (LPARAM)buf);
|
||||
}
|
||||
if (StdOut != NULL)
|
||||
{
|
||||
DWORD bytes_written;
|
||||
WriteFile(StdOut, buf, bpos, &bytes_written, NULL);
|
||||
}
|
||||
}
|
||||
// Restore the previous selection.
|
||||
SendMessage (edit, EM_EXSETSEL, 0, (LPARAM)&selection);
|
||||
// Give the edit control a chance to redraw itself.
|
||||
I_GetEvent ();
|
||||
|
||||
if (edit != NULL)
|
||||
{
|
||||
// If the old selection was at the end of the text, keep it at the end and
|
||||
// scroll. Don't scroll if the selection is anywhere else.
|
||||
if (selection.cpMin == endselection.cpMin && selection.cpMax == endselection.cpMax)
|
||||
{
|
||||
selection.cpMax = selection.cpMin = GetWindowTextLength (edit);
|
||||
lines_after = SendMessage (edit, EM_GETLINECOUNT, 0, 0);
|
||||
if (lines_after > lines_before)
|
||||
{
|
||||
SendMessage (edit, EM_LINESCROLL, 0, lines_after - lines_before);
|
||||
}
|
||||
}
|
||||
// Restore the previous selection.
|
||||
SendMessage (edit, EM_EXSETSEL, 0, (LPARAM)&selection);
|
||||
// Give the edit control a chance to redraw itself.
|
||||
I_GetEvent ();
|
||||
}
|
||||
if (StdOut != NULL && FancyStdOut)
|
||||
{ // Set text back to gray, in case it was changed.
|
||||
SetConsoleTextAttribute(StdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
}
|
||||
}
|
||||
|
||||
EXTERN_CVAR (Bool, queryiwad);
|
||||
|
|
Loading…
Reference in a new issue