Merge branch 'localization' of https://github.com/coelckers/gzdoom into localization

This commit is contained in:
Christoph Oelckers 2019-02-15 10:20:14 +01:00
commit 9fba9eee18
32 changed files with 327 additions and 231 deletions

View file

@ -229,9 +229,7 @@ if( MSVC )
set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd" ) set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd" )
# Disable warnings for unsecure CRT functions from VC8+ # Disable warnings for unsecure CRT functions from VC8+
if( MSVC_VERSION GREATER 1399 ) set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996 /DUNICODE /D_UNICODE" )
set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996" )
endif()
# The CMake configurations set /GR and /MD by default, which conflict with our settings. # The CMake configurations set /GR and /MD by default, which conflict with our settings.
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} ) string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} )

View file

@ -1569,13 +1569,14 @@ void FExecList::AddPullins(TArray<FString> &wads) const
FExecList *C_ParseExecFile(const char *file, FExecList *exec) FExecList *C_ParseExecFile(const char *file, FExecList *exec)
{ {
FILE *f;
char cmd[4096]; char cmd[4096];
int retval = 0; int retval = 0;
if ( (f = fopen (file, "r")) ) FileReader fr;
if ( (fr.OpenFile(file)) )
{ {
while (fgets(cmd, countof(cmd)-1, f)) while (fr.Gets(cmd, countof(cmd)-1))
{ {
// Comments begin with // // Comments begin with //
char *stop = cmd + strlen(cmd) - 1; char *stop = cmd + strlen(cmd) - 1;
@ -1611,11 +1612,6 @@ FExecList *C_ParseExecFile(const char *file, FExecList *exec)
} }
exec->AddCommand(cmd, file); exec->AddCommand(cmd, file);
} }
if (!feof(f))
{
Printf("Error parsing \"%s\"\n", file);
}
fclose(f);
} }
else else
{ {

View file

@ -2679,7 +2679,7 @@ void D_DoomMain (void)
if (StoredWarp.IsNotEmpty()) if (StoredWarp.IsNotEmpty())
{ {
AddCommandString(StoredWarp); AddCommandString(StoredWarp);
StoredWarp = NULL; StoredWarp = "";
} }
} }
else else

View file

@ -933,7 +933,7 @@ void ReadUserInfo(FSerializer &arc, userinfo_t &info, FString &skin)
const char *str; const char *str;
info.Reset(); info.Reset();
skin = NULL; skin = "";
if (arc.BeginObject("userinfo")) if (arc.BeginObject("userinfo"))
{ {
while ((key = arc.GetKey())) while ((key = arc.GetKey()))

View file

@ -1025,7 +1025,7 @@ class CommandDrawNumber : public CommandDrawString
usePrefix(false), interpolationSpeed(0), drawValue(0), length(3), usePrefix(false), interpolationSpeed(0), drawValue(0), length(3),
lowValue(-1), lowTranslation(CR_UNTRANSLATED), highValue(-1), lowValue(-1), lowTranslation(CR_UNTRANSLATED), highValue(-1),
highTranslation(CR_UNTRANSLATED), value(CONSTANT), highTranslation(CR_UNTRANSLATED), value(CONSTANT),
inventoryItem(NULL), cvarName(nullptr) inventoryItem(NULL)
{ {
} }

View file

@ -79,7 +79,7 @@ bool FLumpFile::Open(bool quiet)
Lumps[0].LumpSize = (int)Reader.GetLength(); Lumps[0].LumpSize = (int)Reader.GetLength();
Lumps[0].Namespace = ns_global; Lumps[0].Namespace = ns_global;
Lumps[0].Flags = 0; Lumps[0].Flags = 0;
Lumps[0].FullName = NULL; Lumps[0].FullName = "";
NumLumps = 1; NumLumps = 1;
if (!quiet) if (!quiet)
{ {

View file

@ -187,7 +187,7 @@ bool FWadFile::Open(bool quiet)
Lumps[i].LumpSize = isBigEndian ? BigLong(fileinfo[i].Size) : LittleLong(fileinfo[i].Size); Lumps[i].LumpSize = isBigEndian ? BigLong(fileinfo[i].Size) : LittleLong(fileinfo[i].Size);
Lumps[i].Namespace = ns_global; Lumps[i].Namespace = ns_global;
Lumps[i].Flags = Lumps[i].Compressed? LUMPF_COMPRESSED : 0; Lumps[i].Flags = Lumps[i].Compressed? LUMPF_COMPRESSED : 0;
Lumps[i].FullName = NULL; Lumps[i].FullName = "";
// Check if the lump is within the WAD file and print a warning if not. // Check if the lump is within the WAD file and print a warning if not.
if (Lumps[i].Position + Lumps[i].LumpSize > wadSize || Lumps[i].Position < 0 || Lumps[i].LumpSize < 0) if (Lumps[i].Position + Lumps[i].LumpSize > wadSize || Lumps[i].Position < 0 || Lumps[i].LumpSize < 0)

View file

@ -490,7 +490,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t m
for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize) for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize)
{ {
FResourceLump *lump = (FResourceLump *)p; FResourceLump *lump = (FResourceLump *)p;
lump->FullName = 0; lump->FullName = "";
lump->Name[0] = '\0'; lump->Name[0] = '\0';
lump->Namespace = ns_hidden; lump->Namespace = ns_hidden;
} }
@ -720,7 +720,7 @@ bool FMemoryFile::Open(bool quiet)
Lumps[0].LumpSize = (int)Reader.GetLength(); Lumps[0].LumpSize = (int)Reader.GetLength();
Lumps[0].Namespace = ns_global; Lumps[0].Namespace = ns_global;
Lumps[0].Flags = 0; Lumps[0].Flags = 0;
Lumps[0].FullName = nullptr; Lumps[0].FullName = "";
NumLumps = 1; NumLumps = 1;
return true; return true;
} }

View file

@ -117,7 +117,7 @@ public:
tex.Filter = filter; tex.Filter = filter;
tex.Wrap = wrap; tex.Wrap = wrap;
tex.Type = type; tex.Type = type;
tex.Texture = {}; tex.Texture = "";
} }
void SetOutputTexture(PPTextureName texture) void SetOutputTexture(PPTextureName texture)
@ -129,19 +129,19 @@ public:
void SetOutputCurrent() void SetOutputCurrent()
{ {
Output.Type = PPTextureType::CurrentPipelineTexture; Output.Type = PPTextureType::CurrentPipelineTexture;
Output.Texture = {}; Output.Texture = "";
} }
void SetOutputNext() void SetOutputNext()
{ {
Output.Type = PPTextureType::NextPipelineTexture; Output.Type = PPTextureType::NextPipelineTexture;
Output.Texture = {}; Output.Texture = "";
} }
void SetOutputSceneColor() void SetOutputSceneColor()
{ {
Output.Type = PPTextureType::SceneColor; Output.Type = PPTextureType::SceneColor;
Output.Texture = {}; Output.Texture = "";
} }
void SetNoBlend() void SetNoBlend()

View file

@ -664,9 +664,9 @@ void CALLBACK WinMIDIDevice::CallbackFunc(HMIDIOUT hOut, UINT uMsg, DWORD_PTR dw
static bool IgnoreMIDIVolume(UINT id) static bool IgnoreMIDIVolume(UINT id)
{ {
MIDIOUTCAPS caps; MIDIOUTCAPSA caps;
if (MMSYSERR_NOERROR == midiOutGetDevCaps(id, &caps, sizeof(caps))) if (MMSYSERR_NOERROR == midiOutGetDevCapsA(id, &caps, sizeof(caps)))
{ {
if (caps.wTechnology == MIDIDEV_MAPPER) if (caps.wTechnology == MIDIDEV_MAPPER)
{ {

View file

@ -207,15 +207,18 @@ CCMD (snd_listmididevices)
{ {
for (id = 0; id < nummididevices; ++id) for (id = 0; id < nummididevices; ++id)
{ {
FString text;
res = midiOutGetDevCaps (id, &caps, sizeof(caps)); res = midiOutGetDevCaps (id, &caps, sizeof(caps));
if (res == MMSYSERR_NODRIVER) if (res == MMSYSERR_NODRIVER)
strcpy (caps.szPname, "<Driver not installed>"); text = "<Driver not installed>";
else if (res == MMSYSERR_NOMEM) else if (res == MMSYSERR_NOMEM)
strcpy (caps.szPname, "<No memory for description>"); text = "<No memory for description>";
else if (res != MMSYSERR_NOERROR) else if (res == MMSYSERR_NOERROR)
text = caps.szPname;
else
continue; continue;
PrintMidiDevice (id, caps.szPname, caps.wTechnology, caps.dwSupport); PrintMidiDevice (id, text, caps.wTechnology, caps.dwSupport);
} }
} }
} }

View file

@ -37,6 +37,17 @@
#include "templates.h" #include "templates.h"
FILE *myfopen(const char *filename, const char *flags)
{
#ifndef _WIN32
return fopen(filename, flags);
#else
auto widename = WideString(filename);
auto wideflags = WideString(flags);
return _wfopen(widename.c_str(), wideflags.c_str());
#endif
}
//========================================================================== //==========================================================================
// //
@ -67,7 +78,7 @@ public:
bool Open(const char *filename, long startpos = 0, long len = -1) bool Open(const char *filename, long startpos = 0, long len = -1)
{ {
File = fopen(filename, "rb"); File = myfopen(filename, "rb");
if (File == nullptr) return false; if (File == nullptr) return false;
FilePos = startpos; FilePos = startpos;
StartPos = startpos; StartPos = startpos;
@ -407,7 +418,7 @@ bool FileReader::OpenMemoryArray(std::function<bool(TArray<uint8_t>&)> getter)
bool FileWriter::OpenDirect(const char *filename) bool FileWriter::OpenDirect(const char *filename)
{ {
File = fopen(filename, "wb"); File = myfopen(filename, "wb");
return (File != NULL); return (File != NULL);
} }

View file

@ -41,7 +41,7 @@
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
#define LoadLibrary(x) dlopen((x), RTLD_LAZY) #define LoadLibraryA(x) dlopen((x), RTLD_LAZY)
#define GetProcAddress(a,b) dlsym((a),(b)) #define GetProcAddress(a,b) dlsym((a),(b))
#define FreeLibrary(x) dlclose((x)) #define FreeLibrary(x) dlclose((x))
using HMODULE = void*; using HMODULE = void*;
@ -83,14 +83,14 @@ void FModule::Unload()
bool FModule::Open(const char* lib) bool FModule::Open(const char* lib)
{ {
#ifdef _WIN32 #ifdef _WIN32
if((handle = GetModuleHandle(lib)) != nullptr) if((handle = GetModuleHandleA(lib)) != nullptr)
return true; return true;
#else #else
// Loading an empty string in Linux doesn't do what we expect it to. // Loading an empty string in Linux doesn't do what we expect it to.
if(*lib == '\0') if(*lib == '\0')
return false; return false;
#endif #endif
handle = LoadLibrary(lib); handle = LoadLibraryA(lib);
return handle != nullptr; return handle != nullptr;
} }

View file

@ -1251,6 +1251,51 @@ void FString::Split(TArray<FString>& tokens, const char *delimiter, EmptyTokenTy
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
// Convert from and to Windows wide strings so that we can interface with the Unicode version of the Windows API.
FString::FString(const wchar_t *copyStr)
{
if (copyStr == NULL || *copyStr == '\0')
{
ResetToNull();
}
else
{
auto len = wcslen(copyStr);
int size_needed = WideCharToMultiByte(CP_UTF8, 0, copyStr, (int)len, nullptr, 0, nullptr, nullptr);
AllocBuffer(size_needed);
WideCharToMultiByte(CP_UTF8, 0, copyStr, (int)len, Chars, size_needed, nullptr, nullptr);
}
}
FString &FString::operator=(const wchar_t *copyStr)
{
if (copyStr == NULL || *copyStr == '\0')
{
Data()->Release();
ResetToNull();
}
else
{
auto len = wcslen(copyStr);
int size_needed = WideCharToMultiByte(CP_UTF8, 0, copyStr, (int)len, nullptr, 0, nullptr, nullptr);
ReallocBuffer(size_needed);
WideCharToMultiByte(CP_UTF8, 0, copyStr, (int)len, Chars, size_needed, nullptr, nullptr);
}
return *this;
}
std::wstring WideString(const char *cin)
{
const uint8_t *in = (const uint8_t*)cin;
// This is a bit tricky because we need to support both UTF-8 and legacy content in ISO-8859-1
// and thanks to user-side string manipulation it can be that a text mixes both.
// To convert the string this uses the same function as all text printing in the engine.
TArray<wchar_t> buildbuffer;
while (*in) buildbuffer.Push((wchar_t)GetCharFromString(in));
buildbuffer.Push(0);
return std::wstring(buildbuffer.Data());
}
static HANDLE StringHeap; static HANDLE StringHeap;
const SIZE_T STRING_HEAP_SIZE = 64*1024; const SIZE_T STRING_HEAP_SIZE = 64*1024;
#endif #endif

View file

@ -57,6 +57,9 @@
#define IGNORE_FORMAT_POST #define IGNORE_FORMAT_POST
#endif #endif
#ifdef _WIN32
std::wstring WideString(const char *);
#endif
struct FStringData struct FStringData
{ {
@ -128,6 +131,12 @@ public:
FString (const char *copyStr); FString (const char *copyStr);
FString (const char *copyStr, size_t copyLen); FString (const char *copyStr, size_t copyLen);
FString (char oneChar); FString (char oneChar);
// This is intentionally #ifdef'd. The only code which needs this is parts of the Windows backend that receive Unicode text from the system.
#ifdef _WIN32
explicit FString(const wchar_t *copyStr);
FString &operator = (const wchar_t *copyStr);
std::wstring WideString() const { return ::WideString(Chars); }
#endif
// Concatenation constructors // Concatenation constructors
FString (const FString &head, const FString &tail); FString (const FString &head, const FString &tail);

View file

@ -55,6 +55,8 @@ int ListGetInt(VMVa_List &tags);
// This can handle both ISO 8859-1 and UTF-8, as well as mixed strings // This can handle both ISO 8859-1 and UTF-8, as well as mixed strings
// between both encodings, which may happen if inconsistent encoding is // between both encodings, which may happen if inconsistent encoding is
// used between different files in a mod. // used between different files in a mod.
// The long term goal should be to convert all text to UTF-8 on loading and
// make this require pure UTF-8 input.
// //
//========================================================================== //==========================================================================
@ -66,6 +68,45 @@ int GetCharFromString(const uint8_t *&string)
if (z < 192) if (z < 192)
{ {
// Handle Windows 1252 characters
if (z >= 128 && z < 160)
{
static const uint16_t map0x80_0x9f[] = {
0x20AC,
0x81 ,
0x201A,
0x0192,
0x201E,
0x2026,
0x2020,
0x2021,
0x02C6,
0x2030,
0x0160,
0x2039,
0x0152,
0x8d ,
0x017D,
0x8f ,
0x90 ,
0x2018,
0x2019,
0x201C,
0x201D,
0x2022,
0x2013,
0x2014,
0x02DC,
0x2122,
0x0161,
0x203A,
0x0153,
0x9d ,
0x017E,
0x0178,
};
return map0x80_0x9f[z - 128];
}
return z; return z;
} }
else if (z <= 223) else if (z <= 223)

View file

@ -100,6 +100,7 @@ const char *GetVersionString();
// More stuff that needs to be different for derivatives. // More stuff that needs to be different for derivatives.
#define GAMENAME "GZDoom" #define GAMENAME "GZDoom"
#define WGAMENAME L"GZDoom"
#define GAMENAMELOWERCASE "gzdoom" #define GAMENAMELOWERCASE "gzdoom"
#define FORUM_URL "http://forum.zdoom.org/" #define FORUM_URL "http://forum.zdoom.org/"
#define BUGS_FORUM_URL "http://forum.zdoom.org/viewforum.php?f=2" #define BUGS_FORUM_URL "http://forum.zdoom.org/viewforum.php?f=2"

View file

@ -287,10 +287,10 @@ void SystemBaseFrameBuffer::PositionWindow(bool fullscreen, bool initialcall)
if (!m_Fullscreen && fullscreen && !initialcall) SaveWindowedPos(); if (!m_Fullscreen && fullscreen && !initialcall) SaveWindowedPos();
if (m_Monitor) if (m_Monitor)
{ {
MONITORINFOEX mi; MONITORINFOEXA mi;
mi.cbSize = sizeof mi; mi.cbSize = sizeof mi;
if (GetMonitorInfo(HMONITOR(m_Monitor), &mi)) if (GetMonitorInfoA(HMONITOR(m_Monitor), &mi))
{ {
strcpy(m_displayDeviceNameBuffer, mi.szDevice); strcpy(m_displayDeviceNameBuffer, mi.szDevice);
m_displayDeviceName = m_displayDeviceNameBuffer; m_displayDeviceName = m_displayDeviceNameBuffer;

View file

@ -173,7 +173,7 @@ bool FCDThread::Init ()
CD_WindowClass.style = CS_NOCLOSE; CD_WindowClass.style = CS_NOCLOSE;
CD_WindowClass.lpfnWndProc = CD_WndProc; CD_WindowClass.lpfnWndProc = CD_WndProc;
CD_WindowClass.hInstance = g_hInst; CD_WindowClass.hInstance = g_hInst;
CD_WindowClass.lpszClassName = GAMENAME " CD Player"; CD_WindowClass.lpszClassName = WGAMENAME " CD Player";
CD_WindowAtom = RegisterClass (&CD_WindowClass); CD_WindowAtom = RegisterClass (&CD_WindowClass);
if (CD_WindowAtom == 0) if (CD_WindowAtom == 0)
@ -181,7 +181,7 @@ bool FCDThread::Init ()
CD_Window = CreateWindow ( CD_Window = CreateWindow (
(LPCTSTR)(INT_PTR)(int)CD_WindowAtom, (LPCTSTR)(INT_PTR)(int)CD_WindowAtom,
GAMENAME " CD Player", WGAMENAME " CD Player",
0, 0,
0, 0, 10, 10, 0, 0, 10, 10,
NULL, NULL,
@ -263,12 +263,12 @@ DWORD FCDThread::Dispatch (DWORD method, DWORD parm1, DWORD parm2, DWORD parm3)
DWORD firstTrack, lastTrack, numTracks; DWORD firstTrack, lastTrack, numTracks;
DWORD length; DWORD length;
DWORD openFlags; DWORD openFlags;
char ident[32]; wchar_t ident[32];
switch (method) switch (method)
{ {
case CDM_Init: case CDM_Init:
mciOpen.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_CD_AUDIO; mciOpen.lpstrDeviceType = (LPCWSTR)MCI_DEVTYPE_CD_AUDIO;
openFlags = MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_WAIT; openFlags = MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_WAIT;
if ((signed)parm1 >= 0) if ((signed)parm1 >= 0)
{ {
@ -411,7 +411,7 @@ DWORD FCDThread::Dispatch (DWORD method, DWORD parm1, DWORD parm2, DWORD parm3)
case CDM_GetMediaIdentity: case CDM_GetMediaIdentity:
case CDM_GetMediaUPC: case CDM_GetMediaUPC:
char ident[32]; wchar_t ident[32];
infoParms.lpstrReturn = ident; infoParms.lpstrReturn = ident;
infoParms.dwRetSize = sizeof(ident); infoParms.dwRetSize = sizeof(ident);
@ -423,7 +423,7 @@ DWORD FCDThread::Dispatch (DWORD method, DWORD parm1, DWORD parm2, DWORD parm3)
} }
else else
{ {
return strtoul (ident, NULL, 0); return wcstoul (ident, NULL, 0);
} }
default: default:

View file

@ -397,7 +397,7 @@ DWORD *GetTopOfStack (void *top)
static HANDLE WriteMyMiniDump (void) static HANDLE WriteMyMiniDump (void)
{ {
MINIDUMP_EXCEPTION_INFORMATION exceptor = { DbgThreadID, &CrashPointers, FALSE }; MINIDUMP_EXCEPTION_INFORMATION exceptor = { DbgThreadID, &CrashPointers, FALSE };
char dbghelpPath[MAX_PATH+12], *bs; WCHAR dbghelpPath[MAX_PATH+12], *bs;
WRITEDUMP pMiniDumpWriteDump; WRITEDUMP pMiniDumpWriteDump;
HANDLE file; HANDLE file;
BOOL good = FALSE; BOOL good = FALSE;
@ -405,17 +405,17 @@ static HANDLE WriteMyMiniDump (void)
// Make sure dbghelp.dll and MiniDumpWriteDump are available // Make sure dbghelp.dll and MiniDumpWriteDump are available
// Try loading from the application directory first, then from the search path. // Try loading from the application directory first, then from the search path.
GetModuleFileName (NULL, dbghelpPath, MAX_PATH); GetModuleFileNameW (NULL, dbghelpPath, MAX_PATH);
dbghelpPath[MAX_PATH] = 0; dbghelpPath[MAX_PATH] = 0;
bs = strrchr (dbghelpPath, '\\'); bs = wcsrchr (dbghelpPath, '\\');
if (bs != NULL) if (bs != NULL)
{ {
strcpy (bs + 1, "dbghelp.dll"); wcscpy (bs + 1, L"dbghelp.dll");
dbghelp = LoadLibrary (dbghelpPath); dbghelp = LoadLibraryW (dbghelpPath);
} }
if (dbghelp == NULL) if (dbghelp == NULL)
{ {
dbghelp = LoadLibrary ("dbghelp.dll"); dbghelp = LoadLibraryA ("dbghelp.dll");
if (dbghelp == NULL) if (dbghelp == NULL)
{ {
NeedDbgHelp = true; NeedDbgHelp = true;
@ -852,7 +852,7 @@ HANDLE WriteTextReport ()
static void AddToolHelp (HANDLE file) static void AddToolHelp (HANDLE file)
{ {
HMODULE kernel = GetModuleHandle ("kernel32.dll"); HMODULE kernel = GetModuleHandleA ("kernel32.dll");
if (kernel == NULL) if (kernel == NULL)
return; return;
@ -1251,7 +1251,7 @@ static void StackWalk (HANDLE file, void *dumpaddress, DWORD *topOfStack, DWORD
Writef (file, "\r\nCall trace:\r\n rip=%p <- Here it dies.\r\n", CrashAddress); Writef (file, "\r\nCall trace:\r\n rip=%p <- Here it dies.\r\n", CrashAddress);
kernel = GetModuleHandle("kernel32.dll"); kernel = GetModuleHandleA("kernel32.dll");
if (kernel == NULL || NULL == (RtlLookupFunctionEntry = if (kernel == NULL || NULL == (RtlLookupFunctionEntry =
(RTLLOOKUPFUNCTIONENTRY)GetProcAddress(kernel, "RtlLookupFunctionEntry"))) (RTLLOOKUPFUNCTIONENTRY)GetProcAddress(kernel, "RtlLookupFunctionEntry")))
{ {
@ -1391,18 +1391,18 @@ static void DumpBytes (HANDLE file, uint8_t *address)
static HANDLE CreateTempFile () static HANDLE CreateTempFile ()
{ {
char temppath[MAX_PATH-13]; WCHAR temppath[MAX_PATH-13];
char tempname[MAX_PATH]; WCHAR tempname[MAX_PATH];
if (!GetTempPath (sizeof(temppath), temppath)) if (!GetTempPathW (countof(temppath), temppath))
{ {
temppath[0] = '.'; temppath[0] = '.';
temppath[1] = '\0'; temppath[1] = '\0';
} }
if (!GetTempFileName (temppath, "zdo", 0, tempname)) if (!GetTempFileNameW (temppath, L"zdo", 0, tempname))
{ {
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
return CreateFile (tempname, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, return CreateFileW (tempname, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE|FILE_FLAG_SEQUENTIAL_SCAN, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE|FILE_FLAG_SEQUENTIAL_SCAN,
NULL); NULL);
} }
@ -1939,7 +1939,7 @@ static INT_PTR CALLBACK OverviewDlgProc (HWND hDlg, UINT message, WPARAM wParam,
{ {
if (link->msg == WM_LBUTTONDOWN) if (link->msg == WM_LBUTTONDOWN)
{ {
ShellExecute (NULL, "open", BUGS_FORUM_URL, NULL, NULL, 0); ShellExecuteA (NULL, "open", BUGS_FORUM_URL, NULL, NULL, 0);
SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 1); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 1);
return TRUE; return TRUE;
} }
@ -1965,8 +1965,8 @@ static INT_PTR CALLBACK OverviewDlgProc (HWND hDlg, UINT message, WPARAM wParam,
static INT_PTR CALLBACK CrashDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) static INT_PTR CALLBACK CrashDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
static CHAR overview[] = "Overview"; static WCHAR overview[] = L"Overview";
static CHAR details[] = "Details"; static WCHAR details[] = L"Details";
HWND edit; HWND edit;
TCITEM tcitem; TCITEM tcitem;
RECT tabrect, tcrect; RECT tabrect, tcrect;
@ -1987,14 +1987,14 @@ static INT_PTR CALLBACK CrashDlgProc (HWND hDlg, UINT message, WPARAM wParam, LP
// dialog template, and the resultant window is stored as the lParam for // dialog template, and the resultant window is stored as the lParam for
// the corresponding tab. // the corresponding tab.
tcitem.pszText = overview; tcitem.pszText = overview;
tcitem.lParam = (LPARAM)CreateDialogParam (g_hInst, MAKEINTRESOURCE(IDD_CRASHOVERVIEW), hDlg, OverviewDlgProc, (LPARAM)edit); tcitem.lParam = (LPARAM)CreateDialogParamW (g_hInst, MAKEINTRESOURCE(IDD_CRASHOVERVIEW), hDlg, OverviewDlgProc, (LPARAM)edit);
TabCtrl_InsertItem (edit, 0, &tcitem); TabCtrl_InsertItem (edit, 0, &tcitem);
TabCtrl_GetItemRect (edit, 0, &tabrect); TabCtrl_GetItemRect (edit, 0, &tabrect);
SetWindowPos ((HWND)tcitem.lParam, HWND_TOP, tcrect.left + 3, tcrect.top + tabrect.bottom + 3, 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); tcrect.right - tcrect.left - 8, tcrect.bottom - tcrect.top - tabrect.bottom - 8, 0);
tcitem.pszText = details; tcitem.pszText = details;
tcitem.lParam = (LPARAM)CreateDialogParam (g_hInst, MAKEINTRESOURCE(IDD_CRASHDETAILS), hDlg, DetailsDlgProc, (LPARAM)edit); tcitem.lParam = (LPARAM)CreateDialogParamW (g_hInst, MAKEINTRESOURCE(IDD_CRASHDETAILS), hDlg, DetailsDlgProc, (LPARAM)edit);
TabCtrl_InsertItem (edit, 1, &tcitem); TabCtrl_InsertItem (edit, 1, &tcitem);
SetWindowPos ((HWND)tcitem.lParam, HWND_TOP, tcrect.left + 3, tcrect.top + tabrect.bottom + 3, 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); tcrect.right - tcrect.left - 8, tcrect.bottom - tcrect.top - tabrect.bottom - 8, 0);
@ -2083,7 +2083,7 @@ static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam,
SendMessage (ctrl, LB_RESETCONTENT, 0, 0); SendMessage (ctrl, LB_RESETCONTENT, 0, 0);
for (i = 0; i < NumFiles; ++i) for (i = 0; i < NumFiles; ++i)
{ {
SendMessage (ctrl, LB_ADDSTRING, 0, (LPARAM)TarFiles[i].Filename); SendMessageA (ctrl, LB_ADDSTRING, 0, (LPARAM)TarFiles[i].Filename);
} }
if (j == LB_ERR || j >= i) j = 0; if (j == LB_ERR || j >= i) j = 0;
SendMessage (ctrl, LB_SETCURSEL, j, 0); SendMessage (ctrl, LB_SETCURSEL, j, 0);
@ -2258,7 +2258,7 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
{ {
mysnprintf (sizebuf, countof(sizebuf), "(%lu KB)", size/1024); mysnprintf (sizebuf, countof(sizebuf), "(%lu KB)", size/1024);
} }
SetWindowText (sizedisplay, sizebuf); SetWindowTextA (sizedisplay, sizebuf);
SetWindowLongPtr (edit, GWLP_USERDATA, filenum); SetWindowLongPtr (edit, GWLP_USERDATA, filenum);
@ -3243,21 +3243,21 @@ static void SaveReport (HANDLE file)
sizeof(ofn) sizeof(ofn)
#endif #endif
, }; , };
char filename[256]; WCHAR filename[256];
ofn.lpstrFilter = "Zip file (*.zip)\0*.zip\0"; ofn.lpstrFilter = L"Zip file (*.zip)\0*.zip\0";
strcpy (filename, "CrashReport.zip"); wcscpy (filename, L"CrashReport.zip");
ofn.lpstrFile = filename; ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename); ofn.nMaxFile = countof(filename);
while (GetSaveFileName (&ofn)) while (GetSaveFileNameW (&ofn))
{ {
HANDLE ofile = CreateFile (ofn.lpstrFile, GENERIC_WRITE, 0, NULL, HANDLE ofile = CreateFileW (ofn.lpstrFile, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,
NULL); NULL);
if (ofile == INVALID_HANDLE_VALUE) if (ofile == INVALID_HANDLE_VALUE)
{ {
if (MessageBox (NULL, "Could not open the crash report file", if (MessageBoxA (NULL, "Could not open the crash report file",
"Save As failed", MB_RETRYCANCEL) == IDRETRY) "Save As failed", MB_RETRYCANCEL) == IDRETRY)
{ {
continue; continue;
@ -3306,7 +3306,7 @@ void DisplayCrashLog ()
"detailed information about the crash.\n" "detailed information about the crash.\n"
"\nThis is all that is available:\n\nCode=XXXXXXXX\nAddr=XXXXXXXX"; "\nThis is all that is available:\n\nCode=XXXXXXXX\nAddr=XXXXXXXX";
mysnprintf (ohPoo + countof(ohPoo) - 23, 23, "%08lX\nAddr=%p", CrashCode, CrashAddress); mysnprintf (ohPoo + countof(ohPoo) - 23, 23, "%08lX\nAddr=%p", CrashCode, CrashAddress);
MessageBox (NULL, ohPoo, GAMENAME" Very Fatal Error", MB_OK|MB_ICONSTOP); MessageBoxA (NULL, ohPoo, GAMENAME" Very Fatal Error", MB_OK|MB_ICONSTOP);
if (WinHlp32 != NULL) if (WinHlp32 != NULL)
{ {
FreeLibrary (WinHlp32); FreeLibrary (WinHlp32);
@ -3314,7 +3314,7 @@ void DisplayCrashLog ()
} }
else else
{ {
HMODULE uxtheme = LoadLibrary ("uxtheme.dll"); HMODULE uxtheme = LoadLibraryA ("uxtheme.dll");
if (uxtheme != NULL) if (uxtheme != NULL)
{ {
pEnableThemeDialogTexture = (HRESULT (__stdcall *)(HWND,DWORD))GetProcAddress (uxtheme, "EnableThemeDialogTexture"); pEnableThemeDialogTexture = (HRESULT (__stdcall *)(HWND,DWORD))GetProcAddress (uxtheme, "EnableThemeDialogTexture");

View file

@ -553,7 +553,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (message == WM_WTSSESSION_CHANGE && lParam == (LPARAM)SessionID) if (message == WM_WTSSESSION_CHANGE && lParam == (LPARAM)SessionID)
{ {
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString ("SessionID matched\n"); OutputDebugStringA ("SessionID matched\n");
#endif #endif
// When using fast user switching, XP will lock a session before // When using fast user switching, XP will lock a session before
// disconnecting it, and the session will be unlocked before reconnecting it. // disconnecting it, and the session will be unlocked before reconnecting it.
@ -601,7 +601,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
#ifdef _DEBUG #ifdef _DEBUG
char foo[256]; char foo[256];
mysnprintf (foo, countof(foo), "Session Change: %ld %d\n", lParam, wParam); mysnprintf (foo, countof(foo), "Session Change: %ld %d\n", lParam, wParam);
OutputDebugString (foo); OutputDebugStringA (foo);
#endif #endif
} }
break; break;
@ -640,7 +640,7 @@ bool I_InitInput (void *hwnd)
FindRawInputFunctions(); FindRawInputFunctions();
// Try for DirectInput 8 first, then DirectInput 3 for NT 4's benefit. // Try for DirectInput 8 first, then DirectInput 3 for NT 4's benefit.
DInputDLL = LoadLibrary("dinput8.dll"); DInputDLL = LoadLibraryA("dinput8.dll");
if (DInputDLL != NULL) if (DInputDLL != NULL)
{ {
typedef HRESULT (WINAPI *blah)(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN); typedef HRESULT (WINAPI *blah)(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN);
@ -666,7 +666,7 @@ bool I_InitInput (void *hwnd)
{ {
FreeLibrary(DInputDLL); FreeLibrary(DInputDLL);
} }
DInputDLL = LoadLibrary ("dinput.dll"); DInputDLL = LoadLibraryA ("dinput.dll");
if (DInputDLL == NULL) if (DInputDLL == NULL)
{ {
I_FatalError ("Could not load dinput.dll: %08lx", GetLastError()); I_FatalError ("Could not load dinput.dll: %08lx", GetLastError());
@ -967,7 +967,7 @@ static void FindRawInputFunctions()
{ {
if (!norawinput) if (!norawinput)
{ {
HMODULE user32 = GetModuleHandle("user32.dll"); HMODULE user32 = GetModuleHandleA("user32.dll");
if (user32 == NULL) if (user32 == NULL)
{ {

View file

@ -73,6 +73,7 @@
#include "s_sound.h" #include "s_sound.h"
#include "vm.h" #include "vm.h"
#include "i_system.h" #include "i_system.h"
#include "gstrings.h"
#include "stats.h" #include "stats.h"
#include "st_start.h" #include "st_start.h"
@ -143,10 +144,7 @@ FModule User32Module{"User32"};
namespace OptWin32 { namespace OptWin32 {
#define DYN_WIN32_SYM(x) decltype(x) x{#x} #define DYN_WIN32_SYM(x) decltype(x) x{#x}
DYN_WIN32_SYM(SHGetFolderPathA);
DYN_WIN32_SYM(SHGetKnownFolderPath); DYN_WIN32_SYM(SHGetKnownFolderPath);
DYN_WIN32_SYM(GetLongPathNameA);
DYN_WIN32_SYM(GetMonitorInfoA);
#undef DYN_WIN32_SYM #undef DYN_WIN32_SYM
} // namespace OptWin32 } // namespace OptWin32
@ -422,7 +420,6 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
HBRUSH hbr; HBRUSH hbr;
HGDIOBJ oldfont; HGDIOBJ oldfont;
RECT rect; RECT rect;
int titlelen;
SIZE size; SIZE size;
LOGFONT lf; LOGFONT lf;
TEXTMETRIC tm; TEXTMETRIC tm;
@ -440,7 +437,7 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
lf.lfCharSet = ANSI_CHARSET; lf.lfCharSet = ANSI_CHARSET;
lf.lfWeight = FW_BOLD; lf.lfWeight = FW_BOLD;
lf.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN; lf.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
strcpy (lf.lfFaceName, "Trebuchet MS"); wcscpy (lf.lfFaceName, L"Trebuchet MS");
GameTitleFont = CreateFontIndirect (&lf); GameTitleFont = CreateFontIndirect (&lf);
oldfont = SelectObject (hdc, GetStockObject (DEFAULT_GUI_FONT)); oldfont = SelectObject (hdc, GetStockObject (DEFAULT_GUI_FONT));
@ -459,7 +456,7 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
SelectObject (hdc, oldfont); SelectObject (hdc, oldfont);
// Create log read-only edit control // Create log read-only edit control
view = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "RichEdit20W", NULL, view = CreateWindowExW (WS_EX_NOPARENTNOTIFY, L"RichEdit20W", nullptr,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | WS_CLIPSIBLINGS, ES_LEFT | ES_MULTILINE | WS_CLIPSIBLINGS,
0, 0, 0, 0, 0, 0, 0, 0,
@ -489,8 +486,8 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
ConWindow = view; ConWindow = view;
ReleaseDC (hWnd, hdc); 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); view = CreateWindowExW (WS_EX_NOPARENTNOTIFY, L"STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, 0, 0, 0, 0, hWnd, nullptr, inst, nullptr);
if (view == NULL) if (view == nullptr)
{ {
return -1; return -1;
} }
@ -526,14 +523,14 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
// Calculate width of the title string. // Calculate width of the title string.
SetTextAlign (drawitem->hDC, TA_TOP); SetTextAlign (drawitem->hDC, TA_TOP);
oldfont = SelectObject (drawitem->hDC, GameTitleFont != NULL ? GameTitleFont : (HFONT)GetStockObject (DEFAULT_GUI_FONT)); oldfont = SelectObject (drawitem->hDC, GameTitleFont != NULL ? GameTitleFont : (HFONT)GetStockObject (DEFAULT_GUI_FONT));
titlelen = (int)DoomStartupInfo.Name.Len(); auto widename = DoomStartupInfo.Name.WideString();
GetTextExtentPoint32 (drawitem->hDC, DoomStartupInfo.Name, titlelen, &size); GetTextExtentPoint32W (drawitem->hDC, widename.c_str(), (int)widename.length(), &size);
// Draw the title. // Draw the title.
c = (const PalEntry *)&DoomStartupInfo.FgColor; c = (const PalEntry *)&DoomStartupInfo.FgColor;
SetTextColor (drawitem->hDC, RGB(c->r,c->g,c->b)); SetTextColor (drawitem->hDC, RGB(c->r,c->g,c->b));
SetBkMode (drawitem->hDC, TRANSPARENT); SetBkMode (drawitem->hDC, TRANSPARENT);
TextOut (drawitem->hDC, rect.left + (rect.right - rect.left - size.cx) / 2, 2, DoomStartupInfo.Name, titlelen); TextOutW (drawitem->hDC, rect.left + (rect.right - rect.left - size.cx) / 2, 2, widename.c_str(), (int)widename.length());
SelectObject (drawitem->hDC, oldfont); SelectObject (drawitem->hDC, oldfont);
return TRUE; return TRUE;
} }
@ -555,12 +552,12 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
// where the command prompt would have been in DOS. // where the command prompt would have been in DOS.
if (GameTitleWindow == NULL) if (GameTitleWindow == NULL)
{ {
static const char QuitText[] = "Press any key or click anywhere in the window to quit."; auto quitmsg = WideString(GStrings("TXT_QUITENDOOM"));
SetTextColor (drawitem->hDC, RGB(240,240,240)); SetTextColor (drawitem->hDC, RGB(240,240,240));
SetBkMode (drawitem->hDC, TRANSPARENT); SetBkMode (drawitem->hDC, TRANSPARENT);
oldfont = SelectObject (drawitem->hDC, (HFONT)GetStockObject (DEFAULT_GUI_FONT)); oldfont = SelectObject (drawitem->hDC, (HFONT)GetStockObject (DEFAULT_GUI_FONT));
TextOut (drawitem->hDC, 3, drawitem->rcItem.bottom - DefaultGUIFontHeight - 3, QuitText, countof(QuitText)-1); TextOutW (drawitem->hDC, 3, drawitem->rcItem.bottom - DefaultGUIFontHeight - 3, quitmsg.c_str(), (int)quitmsg.length());
SelectObject (drawitem->hDC, oldfont); SelectObject (drawitem->hDC, oldfont);
} }
return TRUE; return TRUE;
@ -714,12 +711,13 @@ void RestoreConView()
void ShowErrorPane(const char *text) void ShowErrorPane(const char *text)
{ {
if (Window == NULL || ConWindow == NULL) auto widetext = WideString(text);
if (Window == nullptr || ConWindow == nullptr)
{ {
if (text != NULL) if (text != NULL)
{ {
MessageBox (Window, text, MessageBoxW (Window, widetext.c_str(),
GAMESIG " Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL); WGAMENAME " Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
} }
return; return;
} }
@ -730,10 +728,10 @@ void ShowErrorPane(const char *text)
} }
if (text != NULL) if (text != NULL)
{ {
char caption[100]; FStringf caption("Fatal Error - " GAMENAME " %s " X64 " (%s)", GetVersionString(), GetGitTime());
mysnprintf(caption, countof(caption), "Fatal Error - " GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime()); auto wcaption = caption.WideString();
SetWindowText (Window, caption); SetWindowTextW (Window, wcaption.c_str());
ErrorIcon = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, 0, 0, 0, 0, Window, NULL, g_hInst, NULL); ErrorIcon = CreateWindowExW (WS_EX_NOPARENTNOTIFY, L"STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, 0, 0, 0, 0, Window, NULL, g_hInst, NULL);
if (ErrorIcon != NULL) if (ErrorIcon != NULL)
{ {
SetWindowLong (ErrorIcon, GWL_ID, IDC_ICONPIC); SetWindowLong (ErrorIcon, GWL_ID, IDC_ICONPIC);
@ -768,21 +766,21 @@ void ShowErrorPane(const char *text)
paraformat.dwMask = PFM_STARTINDENT | PFM_OFFSETINDENT | PFM_RIGHTINDENT; paraformat.dwMask = PFM_STARTINDENT | PFM_OFFSETINDENT | PFM_RIGHTINDENT;
paraformat.dxStartIndent = paraformat.dxOffset = paraformat.dxRightIndent = 120; paraformat.dxStartIndent = paraformat.dxOffset = paraformat.dxRightIndent = 120;
SendMessage (ConWindow, EM_SETPARAFORMAT, 0, (LPARAM)&paraformat); SendMessage (ConWindow, EM_SETPARAFORMAT, 0, (LPARAM)&paraformat);
SendMessage (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"\n"); SendMessageW (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"\n");
// Find out where the error lines start for the error icon display control. // Find out where the error lines start for the error icon display control.
SendMessage (ConWindow, EM_EXGETSEL, 0, (LPARAM)&end); SendMessage (ConWindow, EM_EXGETSEL, 0, (LPARAM)&end);
ErrorIconChar = end.cpMax; ErrorIconChar = end.cpMax;
// Now start adding the actual error message. // Now start adding the actual error message.
SendMessage (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"Execution could not continue.\n\n"); SendMessageW (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)L"Execution could not continue.\n\n");
// Restore old charformat but with light yellow text. // Restore old charformat but with light yellow text.
oldformat.crTextColor = RGB(255,255,170); oldformat.crTextColor = RGB(255,255,170);
SendMessage (ConWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&oldformat); SendMessage (ConWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&oldformat);
// Add the error text. // Add the error text.
SendMessage (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)text); SendMessageW (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)widetext.c_str());
// Make sure the error text is not scrolled below the window. // Make sure the error text is not scrolled below the window.
SendMessage (ConWindow, EM_LINESCROLL, 0, SendMessage (ConWindow, EM_GETLINECOUNT, 0, 0)); SendMessage (ConWindow, EM_LINESCROLL, 0, SendMessage (ConWindow, EM_GETLINECOUNT, 0, 0));
@ -798,8 +796,7 @@ void ShowErrorPane(const char *text)
{ {
if (bRet == -1) if (bRet == -1)
{ {
MessageBox (Window, text, MessageBoxW (Window, widetext.c_str(), WGAMENAME " Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
GAMESIG " Fatal Error", MB_OK|MB_ICONSTOP|MB_TASKMODAL);
return; return;
} }
else if (!IsDialogMessage (ErrorPane, &msg)) else if (!IsDialogMessage (ErrorPane, &msg))
@ -847,7 +844,7 @@ void DoMain (HINSTANCE hInstance)
// Under XP, get our session ID so we can know when the user changes/locks sessions. // 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 // Since we need to remain binary compatible with older versions of Windows, we
// need to extract the ProcessIdToSessionId function from kernel32.dll manually. // need to extract the ProcessIdToSessionId function from kernel32.dll manually.
HMODULE kernel = GetModuleHandle ("kernel32.dll"); HMODULE kernel = GetModuleHandleA ("kernel32.dll");
if (Args->CheckParm("-stdout")) if (Args->CheckParm("-stdout"))
{ {
@ -917,23 +914,19 @@ void DoMain (HINSTANCE hInstance)
atterm (I_Quit); atterm (I_Quit);
// Figure out what directory the program resides in. // Figure out what directory the program resides in.
char progbuff[1024]; WCHAR progbuff[1024];
if (GetModuleFileName(nullptr, progbuff, sizeof progbuff) == 0) if (GetModuleFileNameW(nullptr, progbuff, sizeof progbuff) == 0)
{ {
I_FatalError("Could not determine program location."); I_FatalError("Could not determine program location.");
} }
progbuff[1023] = '\0'; progbuff[1023] = '\0';
if (auto lastsep = wcsrchr(progbuff, '\\'))
char *program = progbuff;
progdir = program;
program = progdir.LockBuffer();
if (char *lastsep = strrchr(program, '\\'))
{ {
lastsep[1] = '\0'; lastsep[1] = '\0';
} }
FixPathSeperator(program);
progdir.Truncate((long)strlen(program)); progdir = progbuff;
progdir.UnlockBuffer(); FixPathSeperator(progdir);
HDC screenDC = GetDC(0); HDC screenDC = GetDC(0);
int dpi = GetDeviceCaps(screenDC, LOGPIXELSX); int dpi = GetDeviceCaps(screenDC, LOGPIXELSX);
@ -971,12 +964,12 @@ void DoMain (HINSTANCE hInstance)
I_FatalError ("Could not register window class"); I_FatalError ("Could not register window class");
/* create window */ /* create window */
char caption[100]; FStringf caption("" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime());
mysnprintf(caption, countof(caption), "" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime()); std::wstring wcaption = caption.WideString();
Window = CreateWindowEx( Window = CreateWindowEx(
WS_EX_APPWINDOW, WS_EX_APPWINDOW,
(LPCTSTR)WinClassName, (LPCTSTR)WinClassName,
(LPCTSTR)caption, wcaption.c_str(),
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
x, y, width, height, x, y, width, height,
(HWND) NULL, (HWND) NULL,
@ -1273,7 +1266,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
InitCommonControls (); // Load some needed controls and be pretty under XP InitCommonControls (); // Load some needed controls and be pretty under XP
// We need to load riched20.dll so that we can create the control. // We need to load riched20.dll so that we can create the control.
if (NULL == LoadLibrary ("riched20.dll")) if (NULL == LoadLibraryA ("riched20.dll"))
{ {
// This should only happen on basic Windows 95 installations, but since we // This should only happen on basic Windows 95 installations, but since we
// don't support Windows 95, we have no obligation to provide assistance in // don't support Windows 95, we have no obligation to provide assistance in
@ -1357,12 +1350,15 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
// each platform has its own specific version of this function. // each platform has its own specific version of this function.
void I_SetWindowTitle(const char* caption) void I_SetWindowTitle(const char* caption)
{ {
if (caption) std::wstring widecaption;
SetWindowText(Window, (LPCTSTR)caption); if (!caption)
{
FStringf default_caption("" GAMENAME " %s " X64 " (%s)", GetVersionString(), GetGitTime());
widecaption = default_caption.WideString();
}
else else
{ {
char default_caption[100]; widecaption = WideString(caption);
mysnprintf(default_caption, countof(default_caption), "" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime());
SetWindowText(Window, default_caption);
} }
SetWindowText(Window, widecaption.c_str());
} }

View file

@ -68,15 +68,14 @@ bool UseKnownFolders()
// of the program. (e.g. Somebody could add write access while the // of the program. (e.g. Somebody could add write access while the
// program is running.) // program is running.)
static INTBOOL iswritable = -1; static INTBOOL iswritable = -1;
FString testpath;
HANDLE file; HANDLE file;
if (iswritable >= 0) if (iswritable >= 0)
{ {
return !iswritable; return !iswritable;
} }
testpath << progdir << "writest"; std::wstring testpath = progdir.WideString() + L"writest";
file = CreateFile(testpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, file = CreateFile(testpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
if (file != INVALID_HANDLE_VALUE) if (file != INVALID_HANDLE_VALUE)
@ -102,19 +101,14 @@ bool UseKnownFolders()
bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create, FString &path) bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create, FString &path)
{ {
using OptWin32::SHGetFolderPathA;
using OptWin32::SHGetKnownFolderPath; using OptWin32::SHGetKnownFolderPath;
char pathstr[MAX_PATH]; WCHAR pathstr[MAX_PATH];
// SHGetKnownFolderPath knows about more folders than SHGetFolderPath, but is // SHGetKnownFolderPath knows about more folders than SHGetFolderPath, but is
// new to Vista, hence the reason we support both. // new to Vista, hence the reason we support both.
if (!SHGetKnownFolderPath) if (!SHGetKnownFolderPath)
{ {
// NT4 doesn't even have this function.
if (!SHGetFolderPathA)
return false;
if (shell_folder < 0) if (shell_folder < 0)
{ // Not supported by SHGetFolderPath { // Not supported by SHGetFolderPath
return false; return false;
@ -123,7 +117,7 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
{ {
shell_folder |= CSIDL_FLAG_CREATE; shell_folder |= CSIDL_FLAG_CREATE;
} }
if (FAILED(SHGetFolderPathA(NULL, shell_folder, NULL, 0, pathstr))) if (FAILED(SHGetFolderPathW(NULL, shell_folder, NULL, 0, pathstr)))
{ {
return false; return false;
} }
@ -137,18 +131,9 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
{ {
return false; return false;
} }
// FIXME: Support Unicode, at least for filenames. This function path = wpath;
// has no MBCS equivalent, so we have to convert it since we don't
// support Unicode. :(
bool converted = false;
if (WideCharToMultiByte(GetACP(), WC_NO_BEST_FIT_CHARS, wpath, -1,
pathstr, countof(pathstr), NULL, NULL) > 0)
{
path = pathstr;
converted = true;
}
CoTaskMemFree(wpath); CoTaskMemFree(wpath);
return converted; return true;
} }
} }
@ -279,14 +264,14 @@ FString M_GetConfigPath(bool for_reading)
{ {
// Is it valid for a user name to have slashes? // Is it valid for a user name to have slashes?
// Check for them and substitute just in case. // Check for them and substitute just in case.
char *probe = uname; auto probe = uname;
while (*probe != 0) while (*probe != 0)
{ {
if (*probe == '\\' || *probe == '/') if (*probe == '\\' || *probe == '/')
*probe = '_'; *probe = '_';
++probe; ++probe;
} }
path << GAMENAMELOWERCASE "-" << uname << ".ini"; path << GAMENAMELOWERCASE "-" << FString(uname) << ".ini";
} }
else else
{ // Couldn't get user name, so just use zdoom.ini { // Couldn't get user name, so just use zdoom.ini

View file

@ -285,10 +285,10 @@ static void SubsetLanguageIDs(LCID id, LCTYPE type, int idx)
LCID langid; LCID langid;
char *idp; char *idp;
if (!GetLocaleInfo(id, type, buf, 8)) if (!GetLocaleInfoA(id, type, buf, 8))
return; return;
langid = MAKELCID(strtoul(buf, NULL, 16), SORT_DEFAULT); langid = MAKELCID(strtoul(buf, NULL, 16), SORT_DEFAULT);
if (!GetLocaleInfo(langid, LOCALE_SABBREVLANGNAME, buf, 8)) if (!GetLocaleInfoA(langid, LOCALE_SABBREVLANGNAME, buf, 8))
return; return;
idp = (char *)(&LanguageIDs[idx]); idp = (char *)(&LanguageIDs[idx]);
memset (idp, 0, 4); memset (idp, 0, 4);
@ -444,7 +444,7 @@ void I_FatalError(const char *error, ...)
va_start(argptr, error); va_start(argptr, error);
myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr); myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr);
va_end(argptr); va_end(argptr);
OutputDebugString(errortext); OutputDebugStringA(errortext);
// Record error to log (if logging) // Record error to log (if logging)
if (Logfile) if (Logfile)
@ -480,7 +480,7 @@ void I_Error(const char *error, ...)
va_start(argptr, error); va_start(argptr, error);
myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr); myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr);
va_end(argptr); va_end(argptr);
OutputDebugString(errortext); OutputDebugStringA(errortext);
throw CRecoverableError(errortext); throw CRecoverableError(errortext);
} }
@ -768,7 +768,7 @@ static void SetQueryIWad(HWND dialog)
if (!query && queryiwad) if (!query && queryiwad)
{ {
MessageBox(dialog, MessageBoxA(dialog,
"You have chosen not to show this dialog box in the future.\n" "You have chosen not to show this dialog box in the future.\n"
"If you wish to see it again, hold down SHIFT while starting " GAMENAME ".", "If you wish to see it again, hold down SHIFT while starting " GAMENAME ".",
"Don't ask me this again", "Don't ask me this again",
@ -796,12 +796,14 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
case WM_INITDIALOG: case WM_INITDIALOG:
// Add our program name to the window title // Add our program name to the window title
{ {
TCHAR label[256]; WCHAR label[256];
FString newlabel; FString newlabel;
GetWindowText(hDlg, label, countof(label)); GetWindowTextW(hDlg, label, countof(label));
newlabel.Format(GAMESIG " %s: %s", GetVersionString(), label); FString alabel(label);
SetWindowText(hDlg, newlabel.GetChars()); newlabel.Format(GAMESIG " %s: %s", GetVersionString(), alabel.GetChars());
auto wlabel = newlabel.WideString();
SetWindowTextW(hDlg, wlabel.c_str());
} }
// [SP] Upstreamed from Zandronum // [SP] Upstreamed from Zandronum
@ -818,20 +820,20 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
// Set up our version string. // Set up our version string.
sprintf(szString, "Version %s.", GetVersionString()); sprintf(szString, "Version %s.", GetVersionString());
SetDlgItemText (hDlg, IDC_WELCOME_VERSION, szString); SetDlgItemTextA (hDlg, IDC_WELCOME_VERSION, szString);
// Populate the list with all the IWADs found // Populate the list with all the IWADs found
ctrl = GetDlgItem(hDlg, IDC_IWADLIST); ctrl = GetDlgItem(hDlg, IDC_IWADLIST);
for (i = 0; i < NumWads; i++) for (i = 0; i < NumWads; i++)
{ {
FString work;
const char *filepart = strrchr(WadList[i].Path, '/'); const char *filepart = strrchr(WadList[i].Path, '/');
if (filepart == NULL) if (filepart == NULL)
filepart = WadList[i].Path; filepart = WadList[i].Path;
else else
filepart++; filepart++;
work.Format("%s (%s)", WadList[i].Name.GetChars(), filepart); FStringf work("%s (%s)", WadList[i].Name.GetChars(), filepart);
SendMessage(ctrl, LB_ADDSTRING, 0, (LPARAM)work.GetChars()); std::wstring wide = work.WideString();
SendMessage(ctrl, LB_ADDSTRING, 0, (LPARAM)wide.c_str());
SendMessage(ctrl, LB_SETITEMDATA, i, (LPARAM)i); SendMessage(ctrl, LB_SETITEMDATA, i, (LPARAM)i);
} }
SendMessage(ctrl, LB_SETCURSEL, DefaultWad, 0); SendMessage(ctrl, LB_SETCURSEL, DefaultWad, 0);
@ -1177,7 +1179,7 @@ bool I_WriteIniFailed()
); );
errortext.Format ("The config file %s could not be written:\n%s", GameConfig->GetPathName(), lpMsgBuf); errortext.Format ("The config file %s could not be written:\n%s", GameConfig->GetPathName(), lpMsgBuf);
LocalFree (lpMsgBuf); LocalFree (lpMsgBuf);
return MessageBox(Window, errortext.GetChars(), GAMENAME " configuration not saved", MB_ICONEXCLAMATION | MB_RETRYCANCEL) == IDRETRY; return MessageBoxA(Window, errortext.GetChars(), GAMENAME " configuration not saved", MB_ICONEXCLAMATION | MB_RETRYCANCEL) == IDRETRY;
} }
//========================================================================== //==========================================================================
@ -1188,9 +1190,13 @@ bool I_WriteIniFailed()
// //
//========================================================================== //==========================================================================
void *I_FindFirst(const char *filespec, findstate_t *fileinfo) void *I_FindFirst(const char *filespec, findstate_t *fileinfo)
{ {
return FindFirstFileA(filespec, (LPWIN32_FIND_DATAA)fileinfo); static_assert(sizeof(WIN32_FIND_DATAW) == sizeof(fileinfo->FindData), "Findata size mismatch");
auto widespec = WideString(filespec);
fileinfo->UTF8Name = "";
return FindFirstFileW(widespec.c_str(), (LPWIN32_FIND_DATAW)&fileinfo->FindData);
} }
//========================================================================== //==========================================================================
@ -1203,7 +1209,8 @@ void *I_FindFirst(const char *filespec, findstate_t *fileinfo)
int I_FindNext(void *handle, findstate_t *fileinfo) int I_FindNext(void *handle, findstate_t *fileinfo)
{ {
return !FindNextFileA((HANDLE)handle, (LPWIN32_FIND_DATAA)fileinfo); fileinfo->UTF8Name = "";
return !FindNextFileW((HANDLE)handle, (LPWIN32_FIND_DATAW)&fileinfo->FindData);
} }
//========================================================================== //==========================================================================
@ -1219,6 +1226,20 @@ int I_FindClose(void *handle)
return FindClose((HANDLE)handle); return FindClose((HANDLE)handle);
} }
//==========================================================================
//
// I_FindName
//
// Returns the name for an entry
//
//==========================================================================
const char *I_FindName(findstate_t *fileinfo)
{
if (fileinfo->UTF8Name.IsEmpty()) fileinfo->UTF8Name = fileinfo->FindData.Name;
return fileinfo->UTF8Name.GetChars();
}
//========================================================================== //==========================================================================
// //
// QueryPathKey // QueryPathKey
@ -1227,26 +1248,23 @@ int I_FindClose(void *handle)
// //
//========================================================================== //==========================================================================
static bool QueryPathKey(HKEY key, const char *keypath, const char *valname, FString &value) static bool QueryPathKey(HKEY key, const wchar_t *keypath, const wchar_t *valname, FString &value)
{ {
HKEY pathkey; HKEY pathkey;
DWORD pathtype; DWORD pathtype;
DWORD pathlen; DWORD pathlen;
LONG res; LONG res;
value = "";
if(ERROR_SUCCESS == RegOpenKeyEx(key, keypath, 0, KEY_QUERY_VALUE, &pathkey)) if(ERROR_SUCCESS == RegOpenKeyEx(key, keypath, 0, KEY_QUERY_VALUE, &pathkey))
{ {
if (ERROR_SUCCESS == RegQueryValueEx(pathkey, valname, 0, &pathtype, NULL, &pathlen) && if (ERROR_SUCCESS == RegQueryValueEx(pathkey, valname, 0, &pathtype, NULL, &pathlen) &&
pathtype == REG_SZ && pathlen != 0) pathtype == REG_SZ && pathlen != 0)
{ {
// Don't include terminating null in count // Don't include terminating null in count
char *chars = value.LockNewBuffer(pathlen - 1); TArray<wchar_t> chars(pathlen + 1, true);
res = RegQueryValueEx(pathkey, valname, 0, NULL, (LPBYTE)chars, &pathlen); res = RegQueryValueEx(pathkey, valname, 0, NULL, (LPBYTE)chars.Data(), &pathlen);
value.UnlockBuffer(); if (res == ERROR_SUCCESS) value = FString(chars.Data());
if (res != ERROR_SUCCESS)
{
value = "";
}
} }
RegCloseKey(pathkey); RegCloseKey(pathkey);
} }
@ -1268,35 +1286,35 @@ TArray<FString> I_GetGogPaths()
{ {
TArray<FString> result; TArray<FString> result;
FString path; FString path;
FString gamepath; std::wstring gamepath;
#ifdef _WIN64 #ifdef _WIN64
FString gogregistrypath = "Software\\Wow6432Node\\GOG.com\\Games"; std::wstring gogregistrypath = L"Software\\Wow6432Node\\GOG.com\\Games";
#else #else
// If a 32-bit ZDoom runs on a 64-bit Windows, this will be transparently and // If a 32-bit ZDoom runs on a 64-bit Windows, this will be transparently and
// automatically redirected to the Wow6432Node address instead, so this address // automatically redirected to the Wow6432Node address instead, so this address
// should be safe to use in all cases. // should be safe to use in all cases.
FString gogregistrypath = "Software\\GOG.com\\Games"; std::wstring gogregistrypath = "Software\\GOG.com\\Games";
#endif #endif
// Look for Ultimate Doom // Look for Ultimate Doom
gamepath = gogregistrypath + "\\1435827232"; gamepath = gogregistrypath + L"\\1435827232";
if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.c_str(), L"Path", path))
{ {
result.Push(path); // directly in install folder result.Push(path); // directly in install folder
} }
// Look for Doom II // Look for Doom II
gamepath = gogregistrypath + "\\1435848814"; gamepath = gogregistrypath + L"\\1435848814";
if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.c_str(), L"Path", path))
{ {
result.Push(path + "/doom2"); // in a subdirectory result.Push(path + "/doom2"); // in a subdirectory
// If direct support for the Master Levels is ever added, they are in path + /master/wads // If direct support for the Master Levels is ever added, they are in path + /master/wads
} }
// Look for Final Doom // Look for Final Doom
gamepath = gogregistrypath + "\\1435848742"; gamepath = gogregistrypath + L"\\1435848742";
if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.c_str(), L"Path", path))
{ {
// in subdirectories // in subdirectories
result.Push(path + "/TNT"); result.Push(path + "/TNT");
@ -1304,15 +1322,15 @@ TArray<FString> I_GetGogPaths()
} }
// Look for Doom 3: BFG Edition // Look for Doom 3: BFG Edition
gamepath = gogregistrypath + "\\1135892318"; gamepath = gogregistrypath + L"\\1135892318";
if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.c_str(), L"Path", path))
{ {
result.Push(path + "/base/wads"); // in a subdirectory result.Push(path + "/base/wads"); // in a subdirectory
} }
// Look for Strife: Veteran Edition // Look for Strife: Veteran Edition
gamepath = gogregistrypath + "\\1432899949"; gamepath = gogregistrypath + L"\\1432899949";
if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.c_str(), L"Path", path))
{ {
result.Push(path); // directly in install folder result.Push(path); // directly in install folder
} }
@ -1346,9 +1364,9 @@ TArray<FString> I_GetSteamPath()
FString path; FString path;
if (!QueryPathKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", "SteamPath", path)) if (!QueryPathKey(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", L"SteamPath", path))
{ {
if (!QueryPathKey(HKEY_LOCAL_MACHINE, "Software\\Valve\\Steam", "InstallPath", path)) if (!QueryPathKey(HKEY_LOCAL_MACHINE, L"Software\\Valve\\Steam", L"InstallPath", path))
return result; return result;
} }
path += "/SteamApps/common/"; path += "/SteamApps/common/";
@ -1375,7 +1393,7 @@ unsigned int I_MakeRNGSeed()
// If RtlGenRandom is available, use that to avoid increasing the // If RtlGenRandom is available, use that to avoid increasing the
// working set by pulling in all of the crytographic API. // working set by pulling in all of the crytographic API.
HMODULE advapi = GetModuleHandle("advapi32.dll"); HMODULE advapi = GetModuleHandleA("advapi32.dll");
if (advapi != NULL) if (advapi != NULL)
{ {
BOOLEAN (APIENTRY *RtlGenRandom)(void *, ULONG) = BOOLEAN (APIENTRY *RtlGenRandom)(void *, ULONG) =
@ -1414,28 +1432,21 @@ unsigned int I_MakeRNGSeed()
// //
//========================================================================== //==========================================================================
FString I_GetLongPathName(FString shortpath) FString I_GetLongPathName(const FString &shortpath)
{ {
using OptWin32::GetLongPathNameA; std::wstring wshortpath = shortpath.WideString();
DWORD buffsize = GetLongPathNameW(wshortpath.c_str(), nullptr, 0);
// Doesn't exist on NT4
if (!GetLongPathNameA)
return shortpath;
DWORD buffsize = GetLongPathNameA(shortpath.GetChars(), NULL, 0);
if (buffsize == 0) if (buffsize == 0)
{ // nothing to change (it doesn't exist, maybe?) { // nothing to change (it doesn't exist, maybe?)
return shortpath; return shortpath;
} }
TCHAR *buff = new TCHAR[buffsize]; TArray<WCHAR> buff(buffsize, true);
DWORD buffsize2 = GetLongPathNameA(shortpath.GetChars(), buff, buffsize); DWORD buffsize2 = GetLongPathNameW(wshortpath.c_str(), buff.Data(), buffsize);
if (buffsize2 >= buffsize) if (buffsize2 >= buffsize)
{ // Failure! Just return the short path { // Failure! Just return the short path
delete[] buff;
return shortpath; return shortpath;
} }
FString longpath(buff, buffsize2); FString longpath(buff.Data());
delete[] buff;
return longpath; return longpath;
} }

View file

@ -137,7 +137,7 @@ typedef long WLONG_PTR;
#endif #endif
// Wrapper for GetLongPathName // Wrapper for GetLongPathName
FString I_GetLongPathName(FString shortpath); FString I_GetLongPathName(const FString &shortpath);
// Directory searching routines // Directory searching routines
@ -152,12 +152,17 @@ FString I_GetLongPathName(FString shortpath);
struct findstate_t struct findstate_t
{ {
private: private:
uint32_t Attribs; struct WinData
uint32_t Times[3*2]; {
uint32_t Size[2]; uint32_t Attribs;
uint32_t Reserved[2]; uint32_t Times[3 * 2];
char Name[MAX_PATH]; uint32_t Size[2];
char AltName[14]; uint32_t Reserved[2];
wchar_t Name[MAX_PATH];
wchar_t AltName[14];
};
WinData FindData;
FString UTF8Name;
friend void *I_FindFirst(const char *filespec, findstate_t *fileinfo); friend void *I_FindFirst(const char *filespec, findstate_t *fileinfo);
friend int I_FindNext(void *handle, findstate_t *fileinfo); friend int I_FindNext(void *handle, findstate_t *fileinfo);
@ -169,13 +174,10 @@ void *I_FindFirst (const char *filespec, findstate_t *fileinfo);
int I_FindNext (void *handle, findstate_t *fileinfo); int I_FindNext (void *handle, findstate_t *fileinfo);
int I_FindClose (void *handle); int I_FindClose (void *handle);
inline const char *I_FindName(findstate_t *fileinfo) const char *I_FindName(findstate_t *fileinfo);
{
return fileinfo->Name;
}
inline int I_FindAttr(findstate_t *fileinfo) inline int I_FindAttr(findstate_t *fileinfo)
{ {
return fileinfo->Attribs; return fileinfo->FindData.Attribs;
} }
#define FA_RDONLY 0x00000001 #define FA_RDONLY 0x00000001

View file

@ -9,15 +9,10 @@
#include "i_module.h" #include "i_module.h"
extern FModule Kernel32Module;
extern FModule Shell32Module; extern FModule Shell32Module;
extern FModule User32Module;
namespace OptWin32 { namespace OptWin32 {
extern TOptProc<Shell32Module, HRESULT(WINAPI*)(HWND, int, HANDLE, DWORD, LPTSTR)> SHGetFolderPathA;
extern TOptProc<Shell32Module, HRESULT(WINAPI*)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *)> SHGetKnownFolderPath; extern TOptProc<Shell32Module, HRESULT(WINAPI*)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *)> SHGetKnownFolderPath;
extern TOptProc<Kernel32Module, DWORD (WINAPI*)(LPCTSTR, LPTSTR, DWORD)> GetLongPathNameA;
extern TOptProc<User32Module, BOOL(WINAPI*)(HMONITOR, LPMONITORINFO)> GetMonitorInfoA;
} // namespace OptWin32 } // namespace OptWin32

View file

@ -400,7 +400,8 @@ void FBasicStartupScreen::NetInit(const char *message, int numplayers)
{ {
HWND ctl; HWND ctl;
SetDlgItemText (NetStartPane, IDC_NETSTARTMESSAGE, message); std::wstring wmessage = WideString(message);
SetDlgItemTextW (NetStartPane, IDC_NETSTARTMESSAGE, wmessage.c_str());
ctl = GetDlgItem (NetStartPane, IDC_NETSTARTPROGRESS); ctl = GetDlgItem (NetStartPane, IDC_NETSTARTPROGRESS);
if (numplayers == 0) if (numplayers == 0)
@ -416,7 +417,7 @@ void FBasicStartupScreen::NetInit(const char *message, int numplayers)
// If we don't set the PBS_MARQUEE style, then the marquee will never show up. // 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); SetWindowLong (ctl, GWL_STYLE, GetWindowLong (ctl, GWL_STYLE) | PBS_MARQUEE);
} }
SetDlgItemText (NetStartPane, IDC_NETSTARTCOUNT, ""); SetDlgItemTextW (NetStartPane, IDC_NETSTARTCOUNT, L"");
} }
else else
{ {
@ -429,7 +430,7 @@ void FBasicStartupScreen::NetInit(const char *message, int numplayers)
if (numplayers == 1) if (numplayers == 1)
{ {
SendMessage (ctl, PBM_SETPOS, 1, 0); SendMessage (ctl, PBM_SETPOS, 1, 0);
SetDlgItemText (NetStartPane, IDC_NETSTARTCOUNT, ""); SetDlgItemTextW (NetStartPane, IDC_NETSTARTCOUNT, L"");
} }
} }
} }
@ -510,7 +511,7 @@ void FBasicStartupScreen :: NetProgress(int count)
char buf[16]; char buf[16];
mysnprintf (buf, countof(buf), "%d/%d", NetCurPos, NetMaxPos); mysnprintf (buf, countof(buf), "%d/%d", NetCurPos, NetMaxPos);
SetDlgItemText (NetStartPane, IDC_NETSTARTCOUNT, buf); SetDlgItemTextA (NetStartPane, IDC_NETSTARTCOUNT, buf);
SendDlgItemMessage (NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, MIN(NetCurPos, NetMaxPos), 0); SendDlgItemMessage (NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, MIN(NetCurPos, NetMaxPos), 0);
} }
} }
@ -1194,7 +1195,7 @@ void ST_Endoom()
bool ST_Util_CreateStartupWindow () bool ST_Util_CreateStartupWindow ()
{ {
StartupScreen = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "STATIC", NULL, StartupScreen = CreateWindowEx (WS_EX_NOPARENTNOTIFY, L"STATIC", NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW,
0, 0, 0, 0, Window, NULL, g_hInst, NULL); 0, 0, 0, 0, Window, NULL, g_hInst, NULL);
if (StartupScreen == NULL) if (StartupScreen == NULL)

View file

@ -128,11 +128,11 @@ void Win32BaseVideo::GetDisplayDeviceName()
{ {
if (mes.hFoundMonitor) if (mes.hFoundMonitor)
{ {
MONITORINFOEX mi; MONITORINFOEXA mi;
mi.cbSize = sizeof mi; mi.cbSize = sizeof mi;
if (GetMonitorInfo(mes.hFoundMonitor, &mi)) if (GetMonitorInfoA(mes.hFoundMonitor, &mi))
{ {
strcpy(m_DisplayDeviceBuffer, mi.szDevice); strcpy(m_DisplayDeviceBuffer, mi.szDevice);
m_DisplayDeviceName = m_DisplayDeviceBuffer; m_DisplayDeviceName = m_DisplayDeviceBuffer;
@ -159,14 +159,14 @@ static BOOL CALLBACK DumpAdaptersMonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT,
{ {
DumpAdaptersState *state = reinterpret_cast<DumpAdaptersState *>(dwData); DumpAdaptersState *state = reinterpret_cast<DumpAdaptersState *>(dwData);
MONITORINFOEX mi; MONITORINFOEXA mi;
mi.cbSize = sizeof mi; mi.cbSize = sizeof mi;
char moreinfo[64] = ""; char moreinfo[64] = "";
bool active = true; bool active = true;
if (GetMonitorInfo(hMonitor, &mi)) if (GetMonitorInfoA(hMonitor, &mi))
{ {
bool primary = !!(mi.dwFlags & MONITORINFOF_PRIMARY); bool primary = !!(mi.dwFlags & MONITORINFOF_PRIMARY);

View file

@ -124,7 +124,7 @@ HWND Win32GLVideo::InitDummy()
wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL; wc.hbrBackground = NULL;
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.lpszClassName = "GZDoomOpenGLDummyWindow"; wc.lpszClassName = L"GZDoomOpenGLDummyWindow";
//Register window class //Register window class
if (!RegisterClass(&wc)) if (!RegisterClass(&wc))
@ -141,9 +141,9 @@ HWND Win32GLVideo::InitDummy()
AdjustWindowRectEx(&windowRect, style, false, exStyle); AdjustWindowRectEx(&windowRect, style, false, exStyle);
//Create Window //Create Window
if (!(dummy = CreateWindowEx(exStyle, if (!(dummy = CreateWindowExW(exStyle,
"GZDoomOpenGLDummyWindow", L"GZDoomOpenGLDummyWindow",
"GZDOOM", WGAMENAME,
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,
0, 0, 0, 0,
windowRect.right - windowRect.left, windowRect.right - windowRect.left,
@ -152,7 +152,7 @@ HWND Win32GLVideo::InitDummy()
g_hInst, g_hInst,
NULL))) NULL)))
{ {
UnregisterClass("GZDoomOpenGLDummyWindow", g_hInst); UnregisterClassW(L"GZDoomOpenGLDummyWindow", g_hInst);
return 0; return 0;
} }
ShowWindow(dummy, SW_HIDE); ShowWindow(dummy, SW_HIDE);
@ -169,7 +169,7 @@ HWND Win32GLVideo::InitDummy()
void Win32GLVideo::ShutdownDummy(HWND dummy) void Win32GLVideo::ShutdownDummy(HWND dummy)
{ {
DestroyWindow(dummy); DestroyWindow(dummy);
UnregisterClass("GZDoomOpenGLDummyWindow", GetModuleHandle(NULL)); UnregisterClassW(L"GZDoomOpenGLDummyWindow", GetModuleHandle(NULL));
} }

View file

@ -2990,3 +2990,5 @@ TXT_NEED_OPASS = "You need the Oracle Pass!";
TXT_FREED_PRISONERS = "You've freed the prisoners!"; TXT_FREED_PRISONERS = "You've freed the prisoners!";
TXT_DESTROYED_CONVERTER = "You've destroyed the Converter!"; TXT_DESTROYED_CONVERTER = "You've destroyed the Converter!";
TXT_COMPLETED_TRAINING = "Congratulations! You have completed the training area"; TXT_COMPLETED_TRAINING = "Congratulations! You have completed the training area";
TXT_QUITENDOOM = "Press any key or click anywhere in the window to quit.";

View file

@ -15,7 +15,7 @@ struct _ native // These are the global variables, the struct is only here to av
native readonly ui bool netgame; native readonly ui bool netgame;
native readonly bool automapactive; native readonly bool automapactive;
native play uint gameaction; native readonly uint gameaction;
native readonly int gamestate; native readonly int gamestate;
native readonly TextureID skyflatnum; native readonly TextureID skyflatnum;
native readonly Font smallfont; native readonly Font smallfont;

View file

@ -1169,8 +1169,8 @@ class PlayerPawn : Actor
// Strife's player can't run when its health is below 10 // Strife's player can't run when its health is below 10
if (health <= RunHealth) if (health <= RunHealth)
{ {
forward = clamp(forward, -gameinfo.normforwardmove[0], gameinfo.normforwardmove[0]); forward = clamp(forward, -gameinfo.normforwardmove[0]*256, gameinfo.normforwardmove[0]*256);
side = clamp(side, -gameinfo.normsidemove[0], gameinfo.normsidemove[0]); side = clamp(side, -gameinfo.normsidemove[0]*256, gameinfo.normsidemove[0]*256);
} }
// [GRB] // [GRB]