Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

45
engines/bagel/mfc/afx.cpp Normal file
View File

@@ -0,0 +1,45 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
CObject *CRuntimeClass::CreateObject() const {
return m_pfnCreateObject();
}
bool CRuntimeClass::IsDerivedFrom(const CRuntimeClass *pBaseClass) const {
assert(pBaseClass != nullptr);
for (const CRuntimeClass *rtClass = this;
rtClass; rtClass = rtClass->m_pBaseClass) {
if (rtClass == pBaseClass)
return true;
}
return false;
}
} // namespace MFC
} // namespace Bagel

193
engines/bagel/mfc/afx.h Normal file
View File

@@ -0,0 +1,193 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_AFX_H
#define BAGEL_MFC_AFX_H
#include "common/stream.h"
#include "bagel/mfc/minwindef.h"
namespace Bagel {
namespace MFC {
struct CRuntimeClass;
class CObject;
class CException;
class CFileException;
#define DECLARE_DYNAMIC(class_name) \
public: \
static const CRuntimeClass class##class_name; \
virtual const CRuntimeClass *GetRuntimeClass() const override; \
#define RUNTIME_CLASS(class_name) ((const CRuntimeClass *)(&class_name::class##class_name))
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
const CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
RUNTIME_CLASS(base_class_name) }; \
const CRuntimeClass* class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS(class_name); }
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, nullptr)
#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CObject *class_name::CreateObject() \
{ return new class_name; } \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \
class_name::CreateObject)
#define ASSERT_KINDOF(class_name, object) \
assert((object)->IsKindOf(RUNTIME_CLASS(class_name)))
#define ASSERT_VALID(X) assert((X) != nullptr)
struct CRuntimeClass {
const char *m_lpszClassName;
int m_nObjectSize;
unsigned int m_wSchema;
CObject *(*m_pfnCreateObject)();
const CRuntimeClass *m_pBaseClass;
CObject *CreateObject() const;
bool IsDerivedFrom(const CRuntimeClass *pBaseClass) const;
};
class CDumpContext {
};
class CObject {
public:
static const CRuntimeClass classCObject;
public:
CObject();
CObject(const CObject &) = default;
CObject &operator=(const CObject &) = default;
virtual ~CObject() = 0;
virtual const CRuntimeClass *GetRuntimeClass() const;
virtual void AssertValid() const {}
virtual void Dump(CDumpContext &dc) const {}
bool IsKindOf(const CRuntimeClass *pClass) const;
};
class CFile : public CObject {
DECLARE_DYNAMIC(CFile)
public:
// Flag values
enum OpenFlags {
modeRead = (int)0x00000,
modeWrite = (int)0x00001,
modeReadWrite = (int)0x00002,
shareCompat = (int)0x00000,
shareExclusive = (int)0x00010,
shareDenyWrite = (int)0x00020,
shareDenyRead = (int)0x00030,
shareDenyNone = (int)0x00040,
modeNoInherit = (int)0x00080,
typeUnicode = (int)0x00400, // used in derived classes (e.g. CStdioFile) only
modeCreate = (int)0x01000,
modeNoTruncate = (int)0x02000,
typeText = (int)0x04000, // used in derived classes (e.g. CStdioFile) only
typeBinary = (int)0x08000, // used in derived classes (e.g. CStdioFile) only
osNoBuffer = (int)0x10000,
osWriteThrough = (int)0x20000,
osRandomAccess = (int)0x40000,
osSequentialScan = (int)0x80000,
};
enum Attribute {
normal = 0x00, // note: not same as FILE_ATTRIBUTE_NORMAL
readOnly = FILE_ATTRIBUTE_READONLY,
hidden = FILE_ATTRIBUTE_HIDDEN,
system = FILE_ATTRIBUTE_SYSTEM,
volume = 0x08,
directory = FILE_ATTRIBUTE_DIRECTORY,
archive = FILE_ATTRIBUTE_ARCHIVE,
device = FILE_ATTRIBUTE_DEVICE,
temporary = FILE_ATTRIBUTE_TEMPORARY,
sparse = FILE_ATTRIBUTE_SPARSE_FILE,
reparsePt = FILE_ATTRIBUTE_REPARSE_POINT,
compressed = FILE_ATTRIBUTE_COMPRESSED,
offline = FILE_ATTRIBUTE_OFFLINE,
notIndexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
encrypted = FILE_ATTRIBUTE_ENCRYPTED
};
enum SeekPosition {
begin = 0x0, current = 0x1, end = 0x2
};
private:
Common::Stream *_stream = nullptr;
Common::SeekableReadStream *readStream() const;
Common::WriteStream *writeStream() const;
public:
CFile() {}
CFile(const char *lpszFileName, unsigned int nOpenFlags);
~CFile() {
Close();
}
bool Open(const char *lpszFileName,
unsigned int nOpenFlags = CFile::modeRead,
CFileException *pError = nullptr);
void Close();
void Abort();
uint64 SeekToEnd();
void SeekToBegin();
virtual uint64 Seek(int64 lOff, unsigned int nFrom);
virtual uint64 GetLength() const;
virtual uint64 GetPosition() const;
virtual unsigned int Read(void *lpBuf, unsigned int nCount);
virtual void Write(const void *lpBuf, unsigned int nCount);
unsigned int ReadHuge(void *lpBuf, unsigned int nCount) {
return Read(lpBuf, nCount);
}
operator Common::SeekableReadStream *() {
return readStream();
}
operator Common::SeekableReadStream &() {
return *readStream();
}
/**
* Detaches the stream from the CFile
* without destroying it.
*/
Common::SeekableReadStream *detach();
};
/*============================================================================*/
/* Exceptions - Not supported in ScummVM */
class CException {};
class CFileException : public CException {};
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,52 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_AFXEXT_H
#define BAGEL_MFC_AFXEXT_H
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
class CBitmapButton : public CButton {
DECLARE_DYNAMIC(CBitmapButton)
protected:
DECLARE_MESSAGE_MAP()
public:
CBitmap m_bitmap; // normal image (REQUIRED)
CBitmap m_bitmapSel; // selected image (OPTIONAL)
CBitmap m_bitmapFocus; // focused but not selected (OPTIONAL)
CBitmap m_bitmapDisabled; // disabled bitmap (OPTIONAL)
public:
~CBitmapButton() override {
}
void SizeToContent();
};
} // namespace MFC
} // namespace Bagel
#endif

1383
engines/bagel/mfc/afxmsg.h Normal file

File diff suppressed because it is too large Load Diff

136
engines/bagel/mfc/afxres.h Normal file
View File

@@ -0,0 +1,136 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_AFXRES_H
#define BAGEL_MFC_AFXRES_H
namespace Bagel {
namespace MFC {
/////////////////////////////////////////////////////////////////////////////
// Parts of Main Frame
#define AFX_IDW_PANE_FIRST 0xE900 // first pane (256 max)
#define AFX_IDW_PANE_LAST 0xE9ff
#define AFX_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
#define AFX_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
#define AFX_IDW_SIZE_BOX 0xEA20 // size box for splitters
#define AFX_IDW_PANE_SAVE 0xEA21
/////////////////////////////////////////////////////////////////////////////
// Standard Commands
// File commands
#define ID_FILE_NEW 0xE100
#define ID_FILE_OPEN 0xE101
#define ID_FILE_CLOSE 0xE102
#define ID_FILE_SAVE 0xE103
#define ID_FILE_SAVE_AS 0xE104
#define ID_FILE_PAGE_SETUP 0xE105
#define ID_FILE_PRINT_SETUP 0xE106
#define ID_FILE_PRINT 0xE107
#define ID_FILE_PRINT_DIRECT 0xE108
#define ID_FILE_PRINT_PREVIEW 0xE109
#define ID_FILE_UPDATE 0xE10A
#define ID_FILE_SAVE_COPY_AS 0xE10B
#define ID_FILE_SEND_MAIL 0xE10C
#define ID_FILE_NEW_FRAME 0xE10D
#define ID_FILE_MRU_FIRST 0xE110
#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max
#define ID_FILE_MRU_FILE2 0xE111
#define ID_FILE_MRU_FILE3 0xE112
#define ID_FILE_MRU_FILE4 0xE113
#define ID_FILE_MRU_FILE5 0xE114
#define ID_FILE_MRU_FILE6 0xE115
#define ID_FILE_MRU_FILE7 0xE116
#define ID_FILE_MRU_FILE8 0xE117
#define ID_FILE_MRU_FILE9 0xE118
#define ID_FILE_MRU_FILE10 0xE119
#define ID_FILE_MRU_FILE11 0xE11A
#define ID_FILE_MRU_FILE12 0xE11B
#define ID_FILE_MRU_FILE13 0xE11C
#define ID_FILE_MRU_FILE14 0xE11D
#define ID_FILE_MRU_FILE15 0xE11E
#define ID_FILE_MRU_FILE16 0xE11F
#define ID_FILE_MRU_LAST 0xE11F
// Edit commands
#define ID_EDIT_CLEAR 0xE120
#define ID_EDIT_CLEAR_ALL 0xE121
#define ID_EDIT_COPY 0xE122
#define ID_EDIT_CUT 0xE123
#define ID_EDIT_FIND 0xE124
#define ID_EDIT_PASTE 0xE125
#define ID_EDIT_PASTE_LINK 0xE126
#define ID_EDIT_PASTE_SPECIAL 0xE127
#define ID_EDIT_REPEAT 0xE128
#define ID_EDIT_REPLACE 0xE129
#define ID_EDIT_SELECT_ALL 0xE12A
#define ID_EDIT_UNDO 0xE12B
#define ID_EDIT_REDO 0xE12C
// Window commands
#define ID_WINDOW_NEW 0xE130
#define ID_WINDOW_ARRANGE 0xE131
#define ID_WINDOW_CASCADE 0xE132
#define ID_WINDOW_TILE_HORZ 0xE133
#define ID_WINDOW_TILE_VERT 0xE134
#define ID_WINDOW_SPLIT 0xE135
#ifndef RC_INVOKED // code only
#define AFX_IDM_WINDOW_FIRST 0xE130
#define AFX_IDM_WINDOW_LAST 0xE13F
#define AFX_IDM_FIRST_MDICHILD 0xFF00 // window list starts here
#endif //!RC_INVOKED
// Help and App commands
#define ID_APP_ABOUT 0xE140
#define ID_APP_EXIT 0xE141
#define ID_HELP_INDEX 0xE142
#define ID_HELP_FINDER 0xE143
#define ID_HELP_USING 0xE144
#define ID_CONTEXT_HELP 0xE145 // shift-F1
// special commands for processing help
#define ID_HELP 0xE146 // first attempt for F1
#define ID_DEFAULT_HELP 0xE147 // last attempt
// Misc
#define ID_NEXT_PANE 0xE150
#define ID_PREV_PANE 0xE151
// Format
#define ID_FORMAT_FONT 0xE160
// OLE commands
#define ID_OLE_INSERT_NEW 0xE200
#define ID_OLE_EDIT_LINKS 0xE201
#define ID_OLE_EDIT_CONVERT 0xE202
#define ID_OLE_EDIT_CHANGE_ICON 0xE203
#define ID_OLE_EDIT_PROPERTIES 0xE204
#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max
#define ID_OLE_VERB_LAST 0xE21F
#define ID_OLE_VERB_POPUP 0xE220
} // namespace MFC
} // namespace Bagel
#endif

116
engines/bagel/mfc/afxstr.h Normal file
View File

@@ -0,0 +1,116 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_AFXSTR_H
#define BAGEL_MFC_AFXSTR_H
#include "bagel/mfc/minwindef.h"
#include "common/str.h"
namespace Bagel {
namespace MFC {
class CString : public Common::String {
public:
CString() : Common::String() {
}
CString(const char *s) : Common::String(s) {
}
CString(char c) : Common::String(c) {
}
CString(const char *s, int nCount) :
Common::String(s, s + (nCount == -1 ? strlen(s) : nCount)) {
}
char *GetBufferSetLength(size_t nNewLength) {
ensureCapacity(nNewLength + 1, false);
return const_cast<char *>(c_str());
}
void ReleaseBuffer(int nNewLength = -1) {
assert(nNewLength == -1);
*this = CString(c_str());
}
size_t GetLength() const {
return size();
}
bool IsEmpty() const {
return empty();
}
void Empty() {
clear();
}
operator const char *() const {
return c_str();
}
CString &operator+=(const char *str) {
Common::String::operator+=(str);
return *this;
}
CString &operator+=(const Common::String &str) {
Common::String::operator+=(str);
return *this;
}
CString &operator+=(char c) {
Common::String::operator+=(c);
return *this;
}
bool LoadString(unsigned int nID);
};
inline CString operator+(const CString &x, const CString &y) {
CString tmp = x;
tmp += y;
return tmp;
}
inline CString operator+(const char *x, const CString &y) {
CString tmp(x);
tmp += y;
return tmp;
}
inline CString operator+(const CString &x, const char *y) {
CString tmp = x;
tmp += y;
return tmp;
}
inline CString operator+(const CString &x, char y) {
CString tmp = x;
tmp += y;
return tmp;
}
inline CString operator+(char x, const CString &y) {
CString tmp;
tmp += x;
tmp += y;
return tmp;
}
} // namespace MFC
} // namespace Bagel
#endif

2126
engines/bagel/mfc/afxwin.h Normal file

File diff suppressed because it is too large Load Diff

203
engines/bagel/mfc/atltime.h Normal file
View File

@@ -0,0 +1,203 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_ATLTIME_H
#define BAGEL_MFC_ATLTIME_H
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/afxstr.h"
namespace Bagel {
namespace MFC {
typedef long clock_t;
class CTimeSpan {
public:
CTimeSpan();
CTimeSpan(int64 time);
CTimeSpan(
long lDays,
int nHours,
int nMins,
int nSecs);
int64 GetDays() const;
int64 GetTotalHours() const;
long GetHours() const;
int64 GetTotalMinutes() const;
long GetMinutes() const;
int64 GetTotalSeconds() const;
long GetSeconds() const;
int64 GetTimeSpan() const;
CTimeSpan operator+(CTimeSpan span) const;
CTimeSpan operator-(CTimeSpan span) const;
CTimeSpan &operator+=(CTimeSpan span);
CTimeSpan &operator-=(CTimeSpan span);
bool operator==(CTimeSpan span) const;
bool operator!=(CTimeSpan span) const;
bool operator<(CTimeSpan span) const;
bool operator>(CTimeSpan span) const;
bool operator<=(CTimeSpan span) const;
bool operator>=(CTimeSpan span) const;
public:
CString Format(const char *pszFormat) const;
CString Format(unsigned int nID) const;
private:
int64 m_timeSpan;
};
class CTime {
public:
static CTime WINAPI GetCurrentTime();
static bool WINAPI IsValidFILETIME(const FILETIME &ft);
CTime();
CTime(int64 time);
CTime(
int nYear,
int nMonth,
int nDay,
int nHour,
int nMin,
int nSec,
int nDST = -1);
CTime(
uint16 wDosDate,
uint16 wDosTime,
int nDST = -1);
CTime(
const SYSTEMTIME &st,
int nDST = -1);
CTime(
const FILETIME &ft,
int nDST = -1);
CTime &operator=(int64 time);
CTime &operator+=(CTimeSpan span);
CTime &operator-=(CTimeSpan span);
CTimeSpan operator-(CTime time) const;
CTime operator-(CTimeSpan span) const;
CTime operator+(CTimeSpan span) const;
bool operator==(CTime time) const;
bool operator!=(CTime time) const;
bool operator<(CTime time) const;
bool operator>(CTime time) const;
bool operator<=(CTime time) const;
bool operator>=(CTime time) const;
int64 GetTime() const;
int GetYear() const;
int GetMonth() const;
int GetDay() const;
int GetHour() const;
int GetMinute() const;
int GetSecond() const;
int GetDayOfWeek() const;
// formatting using "C" strftime
CString Format(const char *pszFormat) const;
CString FormatGmt(const char *pszFormat) const;
CString Format(unsigned int nFormatID) const;
CString FormatGmt(unsigned int nFormatID) const;
private:
int64 m_time;
};
class CFileTimeSpan {
public:
CFileTimeSpan();
CFileTimeSpan(const CFileTimeSpan &span);
CFileTimeSpan(int64 nSpan);
CFileTimeSpan &operator=(const CFileTimeSpan &span);
CFileTimeSpan &operator+=(CFileTimeSpan span);
CFileTimeSpan &operator-=(CFileTimeSpan span);
CFileTimeSpan operator+(CFileTimeSpan span) const;
CFileTimeSpan operator-(CFileTimeSpan span) const;
bool operator==(CFileTimeSpan span) const;
bool operator!=(CFileTimeSpan span) const;
bool operator<(CFileTimeSpan span) const;
bool operator>(CFileTimeSpan span) const;
bool operator<=(CFileTimeSpan span) const;
bool operator>=(CFileTimeSpan span) const;
int64 GetTimeSpan() const;
void SetTimeSpan(int64 nSpan);
protected:
int64 m_nSpan;
};
class CFileTime : public FILETIME {
public:
CFileTime();
CFileTime(const FILETIME &ft);
CFileTime(uint64 nTime);
static CFileTime WINAPI GetCurrentTime();
CFileTime &operator=(const FILETIME &ft);
CFileTime &operator+=(CFileTimeSpan span);
CFileTime &operator-=(CFileTimeSpan span);
CFileTime operator+(CFileTimeSpan span) const;
CFileTime operator-(CFileTimeSpan span) const;
CFileTimeSpan operator-(CFileTime ft) const;
bool operator==(CFileTime ft) const;
bool operator!=(CFileTime ft) const;
bool operator<(CFileTime ft) const;
bool operator>(CFileTime ft) const;
bool operator<=(CFileTime ft) const;
bool operator>=(CFileTime ft) const;
uint64 GetTime() const;
void SetTime(uint64 nTime);
CFileTime UTCToLocal() const;
CFileTime LocalToUTC() const;
static const uint64 Millisecond = 10000;
static const uint64 Second = Millisecond * static_cast<uint64>(1000);
static const uint64 Minute = Second * static_cast<uint64>(60);
static const uint64 Hour = Minute * static_cast<uint64>(60);
static const uint64 Day = Hour * static_cast<uint64>(24);
static const uint64 Week = Day * static_cast<uint64>(7);
};
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,937 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_ATLTYPES_H
#define BAGEL_MFC_ATLTYPES_H
#include "bagel/mfc/minwindef.h"
namespace Bagel {
namespace MFC {
/////////////////////////////////////////////////////////////////////////////
// Classes declared in this file
class CSize;
class CPoint;
class CRect;
/////////////////////////////////////////////////////////////////////////////
// CSize - An extent, similar to Windows SIZE structure.
class CSize : public tagSIZE {
public:
// Constructors
// construct an uninitialized size
CSize();
// create from two integers
CSize(int initCX, int initCY);
// create from another size
CSize(SIZE initSize);
// create from a point
CSize(POINT initPt);
// create from a uint32: cx = LOWORD(dw) cy = HIWORD(dw)
CSize(uint32 dwSize);
// Operations
bool operator==(SIZE size) const;
bool operator!=(SIZE size) const;
void operator+=(SIZE size);
void operator-=(SIZE size);
void SetSize(int CX, int CY);
// Operators returning CSize values
CSize operator+(SIZE size) const;
CSize operator-(SIZE size) const;
CSize operator-() const;
// Operators returning CPoint values
CPoint operator+(POINT point) const;
CPoint operator-(POINT point) const;
// Operators returning CRect values
CRect operator+(const RECT *lpRect) const;
CRect operator-(const RECT *lpRect) const;
};
/////////////////////////////////////////////////////////////////////////////
// CPoint - A 2-D point, similar to Windows POINT structure.
class CPoint : public tagPOINT {
public:
// Constructors
// create an uninitialized point
CPoint();
// create from two integers
CPoint(
int initX,
int initY);
// create from another point
CPoint(POINT initPt);
// create from a size
CPoint(SIZE initSize);
// create from an LPARAM: x = LOWORD(dw) y = HIWORD(dw)
CPoint(LPARAM dwPoint);
// Operations
// translate the point
void Offset(
int xOffset,
int yOffset);
void Offset(POINT point);
void Offset(SIZE size);
void SetPoint(int X, int Y);
bool operator==(POINT point) const;
bool operator!=(POINT point) const;
void operator+=(SIZE size);
void operator-=(SIZE size);
void operator+=(POINT point);
void operator-=(POINT point);
// Operators returning CPoint values
CPoint operator+(SIZE size) const;
CPoint operator-(SIZE size) const;
CPoint operator-() const;
CPoint operator+(POINT point) const;
// Operators returning CSize values
CSize operator-(POINT point) const;
// Operators returning CRect values
CRect operator+(const RECT *lpRect) const;
CRect operator-(const RECT *lpRect) const;
};
/////////////////////////////////////////////////////////////////////////////
// CRect - A 2-D rectangle, similar to Windows RECT structure.
class CRect : public tagRECT {
public:
// uninitialized rectangle
CRect();
// from left, top, right, and bottom
CRect(
int l,
int t,
int r,
int b);
// copy constructor
CRect(const RECT &srcRect);
// from a pointer to another rect
CRect(const LPCRECT lpSrcRect);
// from a point and size
CRect(const POINT &point, const SIZE &size);
// from two points
CRect(const POINT &topLeft, const POINT &bottomRight);
// Attributes (in addition to RECT members)
// retrieves the width
int Width() const;
// returns the height
int Height() const;
// returns the size
CSize Size() const;
// the geometric center point of the rectangle
CPoint CenterPoint() const;
// swap the left and right
void SwapLeftRight();
static void WINAPI SwapLeftRight(LPRECT lpRect);
// convert between CRect and LPRECT/LPCRECT (no need for &)
operator LPRECT();
operator LPCRECT() const;
// returns true if rectangle has no area
bool IsRectEmpty() const;
// returns true if rectangle is at (0,0) and has no area
bool IsRectNull() const;
// returns true if point is within rectangle
bool PtInRect(POINT point) const;
// Operations
// set rectangle from left, top, right, and bottom
void SetRect(
int x1,
int y1,
int x2,
int y2);
void SetRect(
POINT topLeft,
POINT bottomRight);
// empty the rectangle
void SetRectEmpty();
// copy from another rectangle
void CopyRect(LPCRECT lpSrcRect);
// true if exactly the same as another rectangle
bool EqualRect(LPCRECT lpRect) const;
// Inflate rectangle's width and height by
// x units to the left and right ends of the rectangle
// and y units to the top and bottom.
void InflateRect(
int x,
int y);
// Inflate rectangle's width and height by
// size.cx units to the left and right ends of the rectangle
// and size.cy units to the top and bottom.
void InflateRect(SIZE size);
// Inflate rectangle's width and height by moving individual sides.
// Left side is moved to the left, right side is moved to the right,
// top is moved up and bottom is moved down.
void InflateRect(LPCRECT lpRect);
void InflateRect(
int l,
int t,
int r,
int b);
// deflate the rectangle's width and height without
// moving its top or left
void DeflateRect(
int x,
int y);
void DeflateRect(SIZE size);
void DeflateRect(LPCRECT lpRect);
void DeflateRect(
int l,
int t,
int r,
int b);
// translate the rectangle by moving its top and left
void OffsetRect(
int x,
int y);
void OffsetRect(SIZE size);
void OffsetRect(POINT point);
void NormalizeRect();
// absolute position of rectangle
void MoveToY(int y);
void MoveToX(int x);
void MoveToXY(
int x,
int y);
void MoveToXY(POINT point);
// set this rectangle to intersection of two others
bool IntersectRect(
LPCRECT lpRect1,
LPCRECT lpRect2);
// set this rectangle to bounding union of two others
bool UnionRect(
LPCRECT lpRect1,
LPCRECT lpRect2);
// set this rectangle to minimum of two others
bool SubtractRect(
LPCRECT lpRectSrc1,
LPCRECT lpRectSrc2);
// Additional Operations
void operator=(const RECT &srcRect);
bool operator==(const RECT &rect) const;
bool operator!=(const RECT &rect) const;
void operator+=(POINT point);
void operator+=(SIZE size);
void operator+=(LPCRECT lpRect);
void operator-=(POINT point);
void operator-=(SIZE size);
void operator-=(LPCRECT lpRect);
void operator&=(const RECT &rect);
void operator|=(const RECT &rect);
// Operators returning CRect values
CRect operator+(POINT point) const;
CRect operator-(POINT point) const;
CRect operator+(LPCRECT lpRect) const;
CRect operator+(SIZE size) const;
CRect operator-(SIZE size) const;
CRect operator-(LPCRECT lpRect) const;
CRect operator&(const RECT &rect2) const;
CRect operator|(const RECT &rect2) const;
CRect MulDiv(
int nMultiplier,
int nDivisor) const;
CPoint &TopLeft() {
return *((CPoint *)this);
}
CPoint &BottomRight() {
return *((CPoint *)&right);
}
const CPoint &TopLeft() const {
return *((const CPoint *)this);
}
const CPoint &BottomRight() const {
return *((const CPoint *)&right);
}
};
// CSize
inline CSize::CSize() {
cx = 0;
cy = 0;
}
inline CSize::CSize(
int initCX,
int initCY) {
cx = initCX;
cy = initCY;
}
inline CSize::CSize(SIZE initSize) {
*(SIZE *)this = initSize;
}
inline CSize::CSize(POINT initPt) {
*(POINT *)this = initPt;
}
inline CSize::CSize(uint32 dwSize) {
cx = (short)LOWORD(dwSize);
cy = (short)HIWORD(dwSize);
}
inline bool CSize::operator==(SIZE size) const {
return (cx == size.cx && cy == size.cy);
}
inline bool CSize::operator!=(SIZE size) const {
return (cx != size.cx || cy != size.cy);
}
inline void CSize::operator+=(SIZE size) {
cx += size.cx;
cy += size.cy;
}
inline void CSize::operator-=(SIZE size) {
cx -= size.cx;
cy -= size.cy;
}
inline void CSize::SetSize(
int CX,
int CY) {
cx = CX;
cy = CY;
}
inline CSize CSize::operator+(SIZE size) const {
return CSize(cx + size.cx, cy + size.cy);
}
inline CSize CSize::operator-(SIZE size) const {
return CSize(cx - size.cx, cy - size.cy);
}
inline CSize CSize::operator-() const {
return CSize(-cx, -cy);
}
inline CPoint CSize::operator+(POINT point) const {
return CPoint(cx + point.x, cy + point.y);
}
inline CPoint CSize::operator-(POINT point) const {
return CPoint(cx - point.x, cy - point.y);
}
inline CRect CSize::operator+(const RECT *lpRect) const {
return CRect(lpRect) + *this;
}
inline CRect CSize::operator-(const RECT *lpRect) const {
return CRect(lpRect) - *this;
}
// CPoint
inline CPoint::CPoint() {
x = 0;
y = 0;
}
inline CPoint::CPoint(
int initX,
int initY) {
x = initX;
y = initY;
}
inline CPoint::CPoint(POINT initPt) {
*(POINT *)this = initPt;
}
inline CPoint::CPoint(SIZE initSize) {
*(SIZE *)this = initSize;
}
inline CPoint::CPoint(LPARAM dwPoint) {
x = (short)LOWORD(dwPoint);
y = (short)HIWORD(dwPoint);
}
inline void CPoint::Offset(
int xOffset,
int yOffset) {
x += xOffset;
y += yOffset;
}
inline void CPoint::Offset(POINT point) {
x += point.x;
y += point.y;
}
inline void CPoint::Offset(SIZE size) {
x += size.cx;
y += size.cy;
}
inline void CPoint::SetPoint(
int X,
int Y) {
x = X;
y = Y;
}
inline bool CPoint::operator==(POINT point) const {
return (x == point.x && y == point.y);
}
inline bool CPoint::operator!=(POINT point) const {
return (x != point.x || y != point.y);
}
inline void CPoint::operator+=(SIZE size) {
x += size.cx;
y += size.cy;
}
inline void CPoint::operator-=(SIZE size) {
x -= size.cx;
y -= size.cy;
}
inline void CPoint::operator+=(POINT point) {
x += point.x;
y += point.y;
}
inline void CPoint::operator-=(POINT point) {
x -= point.x;
y -= point.y;
}
inline CPoint CPoint::operator+(SIZE size) const {
return CPoint(x + size.cx, y + size.cy);
}
inline CPoint CPoint::operator-(SIZE size) const {
return CPoint(x - size.cx, y - size.cy);
}
inline CPoint CPoint::operator-() const {
return CPoint(-x, -y);
}
inline CPoint CPoint::operator+(POINT point) const {
return CPoint(x + point.x, y + point.y);
}
inline CSize CPoint::operator-(POINT point) const {
return CSize(x - point.x, y - point.y);
}
inline CRect CPoint::operator+(const RECT *lpRect) const {
return CRect(lpRect) + *this;
}
inline CRect CPoint::operator-(const RECT *lpRect) const {
return CRect(lpRect) - *this;
}
// CRect
inline CRect::CRect() {
left = 0;
top = 0;
right = 0;
bottom = 0;
}
inline CRect::CRect(
int l,
int t,
int r,
int b) {
left = l;
top = t;
right = r;
bottom = b;
}
inline CRect::CRect(const RECT &srcRect) {
CopyRect(&srcRect);
}
inline CRect::CRect(LPCRECT lpSrcRect) {
CopyRect(lpSrcRect);
}
inline CRect::CRect(const POINT &point, const SIZE &size) {
right = (left = point.x) + size.cx;
bottom = (top = point.y) + size.cy;
}
inline CRect::CRect(const POINT &topLeft, const POINT &bottomRight) {
left = topLeft.x;
top = topLeft.y;
right = bottomRight.x;
bottom = bottomRight.y;
}
inline int CRect::Width() const {
return right - left;
}
inline int CRect::Height() const {
return bottom - top;
}
inline CSize CRect::Size() const {
return CSize(right - left, bottom - top);
}
inline CPoint CRect::CenterPoint() const {
return CPoint((left + right) / 2, (top + bottom) / 2);
}
inline void CRect::SwapLeftRight() {
SwapLeftRight(LPRECT(this));
}
inline void WINAPI CRect::SwapLeftRight(LPRECT lpRect) {
long temp = lpRect->left;
lpRect->left = lpRect->right;
lpRect->right = temp;
}
inline CRect::operator LPRECT() {
return this;
}
inline CRect::operator LPCRECT() const {
return this;
}
inline bool CRect::IsRectEmpty() const {
return (left >= right) && (top >= bottom);
}
inline bool CRect::IsRectNull() const {
return (left == 0 && right == 0 && top == 0 && bottom == 0);
}
inline bool CRect::PtInRect(POINT point) const {
return (point.x >= left) && (point.x < right) &&
(point.y >= top) && (point.y < bottom);
}
inline void CRect::SetRect(int x1, int y1,
int x2, int y2) {
left = x1;
top = y1;
right = x2;
bottom = y2;
}
inline void CRect::SetRect(
POINT topLeft,
POINT bottomRight) {
left = topLeft.x;
top = topLeft.y;
right = bottomRight.x;
bottom = bottomRight.y;
}
inline void CRect::SetRectEmpty() {
left = top = right = bottom = 0;
}
inline void CRect::CopyRect(LPCRECT lpSrcRect) {
left = lpSrcRect->left;
top = lpSrcRect->top;
right = lpSrcRect->right;
bottom = lpSrcRect->bottom;
}
inline bool CRect::EqualRect(LPCRECT lpRect) const {
return left == lpRect->left &&
top == lpRect->top &&
right == lpRect->right &&
bottom == lpRect->bottom;
}
inline void CRect::InflateRect(
int x, int y) {
left -= x;
top -= y;
right += x;
bottom += y;
}
inline void CRect::InflateRect(SIZE size) {
left -= size.cx;
top -= size.cy;
right += size.cx;
bottom += size.cy;
}
inline void CRect::DeflateRect(
int x, int y) {
InflateRect(-x, -y);
}
inline void CRect::DeflateRect(SIZE size) {
InflateRect(-size.cx, -size.cy);
}
inline void CRect::OffsetRect(
int x, int y) {
left += x;
top += y;
right += x;
bottom += y;
}
inline void CRect::OffsetRect(POINT point) {
left += point.x;
top += point.y;
right += point.x;
bottom += point.y;
}
inline void CRect::OffsetRect(SIZE size) {
OffsetRect(size.cx, size.cy);
}
inline void CRect::MoveToY(int y) {
bottom = Height() + y;
top = y;
}
inline void CRect::MoveToX(int x) {
right = Width() + x;
left = x;
}
inline void CRect::MoveToXY(
int x,
int y) {
MoveToX(x);
MoveToY(y);
}
inline void CRect::MoveToXY(POINT pt) {
MoveToX(pt.x);
MoveToY(pt.y);
}
inline bool CRect::IntersectRect(
LPCRECT lpRect1, LPCRECT lpRect2) {
Common::Rect r = Common::Rect(*lpRect1).findIntersectingRect(*lpRect2);
SetRect(r.left, r.top, r.right, r.bottom);
return !r.isEmpty();
}
inline bool CRect::UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) {
if (!lpRect1 || !lpRect2) {
// Defensive: null input treated as empty
SetRect(0, 0, 0, 0);
return false;
}
// Check for empty rects
bool empty1 = lpRect1->left >= lpRect1->right || lpRect1->top >= lpRect1->bottom;
bool empty2 = lpRect2->left >= lpRect2->right || lpRect2->top >= lpRect2->bottom;
if (empty1 && empty2) {
SetRect(0, 0, 0, 0);
return false;
} else if (empty1) {
*this = *lpRect2;
return true;
} else if (empty2) {
*this = *lpRect1;
return true;
}
// Compute union of two valid rects
left = MIN(lpRect1->left, lpRect2->left);
top = MIN(lpRect1->top, lpRect2->top);
right = MAX(lpRect1->right, lpRect2->right);
bottom = MAX(lpRect1->bottom, lpRect2->bottom);
return true;
}
inline void CRect::operator=(const RECT &srcRect) {
CopyRect(&srcRect);
}
inline bool CRect::operator==(const RECT &rect) const {
return EqualRect(&rect);
}
inline bool CRect::operator!=(const RECT &rect) const {
return !EqualRect(&rect);
}
inline void CRect::operator+=(POINT point) {
OffsetRect(point.x, point.y);
}
inline void CRect::operator+=(SIZE size) {
OffsetRect(size.cx, size.cy);
}
inline void CRect::operator+=(LPCRECT lpRect) {
InflateRect(lpRect);
}
inline void CRect::operator-=(POINT point) {
OffsetRect(-point.x, -point.y);
}
inline void CRect::operator-=(SIZE size) {
OffsetRect(-size.cx, -size.cy);
}
inline void CRect::operator-=(LPCRECT lpRect) {
DeflateRect(lpRect);
}
inline void CRect::operator&=(const RECT &rect) {
IntersectRect(this, &rect);
}
inline void CRect::operator|=(const RECT &rect) {
UnionRect(this, &rect);
}
inline CRect CRect::operator+(POINT pt) const {
CRect rect(*this);
rect.OffsetRect(pt.x, pt.y);
return rect;
}
inline CRect CRect::operator-(POINT pt) const {
CRect rect(*this);
rect.OffsetRect(-pt.x, -pt.y);
return rect;
}
inline CRect CRect::operator+(SIZE size) const {
CRect rect(*this);
rect.OffsetRect(size.cx, size.cy);
return rect;
}
inline CRect CRect::operator-(SIZE size) const {
CRect rect(*this);
rect.OffsetRect(-size.cx, -size.cy);
return rect;
}
inline CRect CRect::operator+(LPCRECT lpRect) const {
CRect rect(this);
rect.InflateRect(lpRect);
return rect;
}
inline CRect CRect::operator-(LPCRECT lpRect) const {
CRect rect(this);
rect.DeflateRect(lpRect);
return rect;
}
inline CRect CRect::operator&(const RECT &rect2) const {
CRect rect;
rect.IntersectRect(this, &rect2);
return rect;
}
inline CRect CRect::operator|(const RECT &rect2) const {
CRect rect;
rect.UnionRect(this, &rect2);
return rect;
}
inline bool CRect::SubtractRect(
LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) {
// Calculate the intersection of the two rectangles
CRect intersect;
if (!intersect.IntersectRect(lpRectSrc1, lpRectSrc2)) {
// No overlap - return full original
*this = *lpRectSrc1;
return true;
}
// If lpRectSrc2 fully covers lpRectSrc1, result is empty
if (intersect == *lpRectSrc1) {
SetRectEmpty();
return false;
}
// Try to return a remaining portion that is a single rectangle
// Top strip
if (intersect.top > lpRectSrc1->top &&
intersect.left <= lpRectSrc1->left &&
intersect.right >= lpRectSrc1->right) {
SetRect(lpRectSrc1->left, lpRectSrc1->top,
lpRectSrc1->right, intersect.top);
return true;
}
// Bottom strip
if (intersect.bottom < lpRectSrc1->bottom &&
intersect.left <= lpRectSrc1->left &&
intersect.right >= lpRectSrc1->right) {
SetRect(lpRectSrc1->left, intersect.bottom,
lpRectSrc1->right, lpRectSrc1->bottom);
return true;
}
// Left strip
if (intersect.left > lpRectSrc1->left &&
intersect.top <= lpRectSrc1->top &&
intersect.bottom >= lpRectSrc1->bottom) {
SetRect(lpRectSrc1->left, lpRectSrc1->top,
intersect.left, lpRectSrc1->bottom);
return true;
}
// Right strip
if (intersect.right < lpRectSrc1->right &&
intersect.top <= lpRectSrc1->top &&
intersect.bottom >= lpRectSrc1->bottom) {
SetRect(intersect.right, lpRectSrc1->top,
lpRectSrc1->right, lpRectSrc1->bottom);
return true;
}
// If none of the simple cases apply, we can't represent the subtraction
// as a single rectangle - result is undefined
SetRectEmpty();
return false;
}
inline void CRect::NormalizeRect() {
int nTemp;
if (left > right) {
nTemp = left;
left = right;
right = nTemp;
}
if (top > bottom) {
nTemp = top;
top = bottom;
bottom = nTemp;
}
}
inline void CRect::InflateRect(LPCRECT lpRect) {
left -= lpRect->left;
top -= lpRect->top;
right += lpRect->right;
bottom += lpRect->bottom;
}
inline void CRect::InflateRect(
int l,
int t,
int r,
int b) {
left -= l;
top -= t;
right += r;
bottom += b;
}
inline void CRect::DeflateRect(LPCRECT lpRect) {
left += lpRect->left;
top += lpRect->top;
right -= lpRect->right;
bottom -= lpRect->bottom;
}
inline void CRect::DeflateRect(
int l,
int t,
int r,
int b) {
left += l;
top += t;
right -= r;
bottom -= b;
}
inline int SafeMulDiv(int a, int b, int c) {
if (c == 0)
return 0; // Or handle divide-by-zero error
// Use 64-bit intermediate result to avoid overflow
int64 temp = (int64)a * (int64)b;
// Round to nearest
if ((temp >= 0))
return (int)((temp + (c / 2)) / c);
else
return (int)((temp - (c / 2)) / c);
}
inline CRect CRect::MulDiv(
int nMultiplier,
int nDivisor) const {
return CRect(
SafeMulDiv(left, nMultiplier, nDivisor),
SafeMulDiv(top, nMultiplier, nDivisor),
SafeMulDiv(right, nMultiplier, nDivisor),
SafeMulDiv(bottom, nMultiplier, nDivisor));
}
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,113 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
bool CBitmap::Attach(HBITMAP hObject) {
return CGdiObject::Attach(hObject);
}
HBITMAP CBitmap::Detach() {
return (HBITMAP)CGdiObject::Detach();
}
bool CBitmap::CreateCompatibleBitmap(CDC *pDC, int nWidth, int nHeight) {
const CDC::Impl *dc = static_cast<CDC::Impl *>(pDC->m_hDC);
Gfx::Surface *src = dc->getSurface();
BITMAPINFOHEADER h;
h.biSize = 40;
h.biWidth = nWidth;
h.biHeight = nHeight;
h.biPlanes = 1;
h.biBitCount = src->format.bytesPerPixel * 8;
h.biCompression = BI_RGB;
h.biSizeImage = 0;
h.biXPelsPerMeter = 0;
h.biYPelsPerMeter = 0;
h.biClrUsed = 0;
h.biClrImportant = 0;
m_hObject = CreateDIBitmap(nullptr, &h,
0, nullptr, nullptr, DIB_RGB_COLORS);
// This is where it becomes permanent
AfxHookObject();
return true;
}
bool CBitmap::CreateBitmap(int nWidth, int nHeight, unsigned int nPlanes,
unsigned int nBitcount, const void *lpBits) {
assert(nPlanes == 1);
BITMAPINFOHEADER h;
h.biSize = 40;
h.biWidth = nWidth;
h.biHeight = nHeight;
h.biPlanes = 1;
h.biBitCount = nBitcount;
h.biCompression = BI_RGB;
h.biSizeImage = 0;
h.biXPelsPerMeter = 0;
h.biYPelsPerMeter = 0;
h.biClrUsed = 0;
h.biClrImportant = 0;
m_hObject = CreateDIBitmap(nullptr, &h,
lpBits ? CBM_INIT : 0, lpBits, nullptr, DIB_RGB_COLORS);
// This is where it becomes permanent
AfxHookObject();
return true;
}
int CBitmap::GetObject(int nCount, void *lpObject) const {
CBitmap::Impl *src = static_cast<CBitmap::Impl *>(m_hObject);
BITMAP *dest = (BITMAP *)lpObject;
assert(src && nCount == sizeof(BITMAP));
dest->bmType = 0;
dest->bmWidth = src->w;
dest->bmHeight = src->h;
dest->bmWidthBytes = src->pitch * src->format.bytesPerPixel;
dest->bmPlanes = 1;
dest->bmBitsPixel = src->format.bpp();
dest->bmBits = src->getPixels();
return sizeof(BITMAP);
}
long CBitmap::GetBitmapBits(long dwCount, void *lpBits) const {
const CBitmap::Impl *src = static_cast<CBitmap::Impl *>(m_hObject);
dwCount = MIN<int32>((int32)dwCount, src->pitch * src->h * src->format.bytesPerPixel);
Common::copy((const byte *)src->getPixels(),
(const byte *)src->getPixels() + dwCount,
(byte *)lpBits);
return dwCount;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,37 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxext.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CBitmapButton, CButton)
BEGIN_MESSAGE_MAP(CBitmapButton, CButton)
END_MESSAGE_MAP()
void CBitmapButton::SizeToContent() {
error("TODO: CBitmapButton::SizeToContent");
}
} // namespace MFC
} // namespace Bagel

108
engines/bagel/mfc/brush.cpp Normal file
View File

@@ -0,0 +1,108 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
CBrush::CBrush() {
}
CBrush::CBrush(CBitmap *pBitmap) {
m_hObject = new Impl(pBitmap);
}
CBrush::CBrush(COLORREF crColor) {
CreateSolidBrush(crColor);
}
CBrush::CBrush(int nIndex, COLORREF crColor) {
m_hObject = new Impl(nIndex, crColor);
}
bool CBrush::CreateSolidBrush(COLORREF crColor) {
DeleteObject();
m_hObject = new Impl(crColor);
AfxHookObject();
return true;
}
bool CBrush::CreateBrushIndirect(const LOGBRUSH *lpLogBrush) {
DeleteObject();
m_hObject = new Impl(lpLogBrush->lbStyle,
lpLogBrush->lbColor);
AfxHookObject();
return true;
}
bool CBrush::CreateStockObject(int nIndex) {
switch (nIndex) {
case WHITE_BRUSH:
CreateSolidBrush(RGB(255, 255, 255));
break;
case LTGRAY_BRUSH:
CreateSolidBrush(RGB(192, 192, 192));
break;
case GRAY_BRUSH:
CreateSolidBrush(RGB(160, 160, 160));
break;
case DKGRAY_BRUSH:
CreateSolidBrush(RGB(128, 128, 128));
break;
case BLACK_BRUSH:
CreateSolidBrush(RGB(0, 0, 0));
break;
default:
error("TODO: CreateStockObject");
break;
}
return true;
}
/*--------------------------------------------*/
CBrush::Impl::Impl() : _type(HS_HORIZONTAL) {
}
CBrush::Impl::Impl(COLORREF crColor) : _color(crColor),
_type(HS_HORIZONTAL) {
}
CBrush::Impl::Impl(int nIndex, COLORREF crColor) :
_type(nIndex), _color(crColor) {
}
CBrush::Impl::Impl(CBitmap *pBitmap) :
_type(HS_HORIZONTAL) {
error("TODO: CBrush::Impl for bitmaps");
}
byte CBrush::Impl::getColor() const {
return AfxGetApp()->getColor(_color);
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,286 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CButton, CWnd)
BEGIN_MESSAGE_MAP(CButton, CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_MESSAGE(BM_CLICK, CButton::OnBnClicked)
ON_MESSAGE(BM_SETCHECK, CButton::OnBnSetCheck)
END_MESSAGE_MAP()
bool CButton::Create(const char *lpszCaption, uint32 dwStyle,
const RECT &rect, CWnd *pParentWnd, unsigned int nID) {
return CWnd::Create("BUTTON", lpszCaption, dwStyle, rect,
pParentWnd, nID);
}
int CButton::GetCheck() const {
return (_itemState & ODS_CHECKED) != 0 ?
BST_CHECKED : BST_UNCHECKED;
}
void CButton::SetCheck(int nCheck) {
SendMessage(BM_SETCHECK, nCheck);
}
void CButton::SetButtonStyle(unsigned int nStyle, bool bRedraw) {
m_nStyle = (m_nStyle & ~0xf) | nStyle;
Invalidate();
}
unsigned int CButton::GetButtonStyle() const {
return GetStyle() & 0xf;
}
void CButton::OnPaint() {
switch (GetButtonStyle()) {
case BS_PUSHBUTTON:
case BS_DEFPUSHBUTTON:
OnPushButtonPaint();
break;
case BS_PUSHBOX:
OnPushBoxPaint();
break;
case BS_OWNERDRAW:
OnOwnerDrawPaint();
break;
default: {
// Fallback for unhandled button types
RECT clientRect;
GetClientRect(&clientRect);
CPaintDC dc(this);
dc.FillSolidRect(&clientRect, RGB(255, 255, 255));
break;
}
}
}
void CButton::OnPushButtonPaint() {
CPaintDC dc(this);
// Get the client rectangle of the window
CRect rect;
GetClientRect(&rect);
// Determine state
bool isEnabled = IsWindowEnabled();
// Choose background color based on state
COLORREF bgColor = isEnabled ? RGB(240, 240, 240) : RGB(200, 200, 200);
dc.FillSolidRect(rect, bgColor);
if (_pressed) {
dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT);
} else {
dc.DrawEdge(&rect, EDGE_RAISED, BF_RECT);
}
// Draw text
CString text;
GetWindowText(text);
dc.SetBkMode(TRANSPARENT);
dc.DrawText(text, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
void CButton::OnPushBoxPaint() {
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
// Choose colors
COLORREF clrFace = GetSysColor(COLOR_BTNFACE);
COLORREF clrHighlight = GetSysColor(COLOR_BTNHIGHLIGHT); // Top/left
COLORREF clrShadow = GetSysColor(COLOR_BTNSHADOW); // Bottom/right
COLORREF clrText = GetSysColor(COLOR_BTNTEXT);
// Fill background
dc.FillSolidRect(rect, clrFace);
// Draw 3D border
if (_pressed) {
// Inset border (pressed look)
dc.Draw3dRect(rect, clrShadow, clrHighlight);
rect.DeflateRect(1, 1);
dc.Draw3dRect(rect, clrShadow, clrHighlight);
} else {
// Raised border (normal look)
dc.Draw3dRect(rect, clrHighlight, clrShadow);
rect.DeflateRect(1, 1);
dc.Draw3dRect(rect, clrHighlight, clrShadow);
}
// Adjust text position if pressed
CPoint offset = _pressed ? CPoint(1, 1) : CPoint(0, 0);
// Draw button text
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(clrText);
dc.SelectObject(GetStockObject(SYSTEM_FONT));
CRect textRect = rect;
textRect.OffsetRect(offset);
dc.DrawText(_windowText, &textRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
// Draw focus rectangle
if (_hasFocus) {
CRect focusRect = rect;
focusRect.DeflateRect(3, 3);
dc.DrawFocusRect(&focusRect);
}
}
void CButton::OnOwnerDrawPaint() {
// Prepare the draw item struct
DRAWITEMSTRUCT dis = { 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0 };
dis.CtlType = ODT_BUTTON;
dis.CtlID = GetDlgCtrlID();
dis.itemID = 0;
dis.itemAction = ODA_DRAWENTIRE;
dis.itemState = 0;
if (IsWindowEnabled())
dis.itemState |= ODS_ENABLED;
else
dis.itemState |= ODS_DISABLED;
if ((GetState() & ODS_CHECKED) != 0 || _pressed)
dis.itemState |= ODS_SELECTED;
if (GetFocus() == this)
dis.itemState |= ODS_FOCUS;
dis.hwndItem = m_hWnd;
// Get the client rect for the button
GetClientRect(&dis.rcItem);
// Get a DC for drawing
PAINTSTRUCT paintStruct;
HDC hdc = BeginPaint(&paintStruct);
dis.hDC = hdc;
// Send WM_DRAWITEM to the parent window
GetParent()->SendMessage(WM_DRAWITEM,
dis.CtlID, (LPARAM)&dis);
EndPaint(&paintStruct);
}
void CButton::OnLButtonDown(unsigned int nFlags, CPoint point) {
if (!(_itemState & ODS_DISABLED)) {
SetCapture();
_pressed = true;
Invalidate();
}
}
void CButton::OnLButtonUp(unsigned int nFlags, CPoint point) {
if (GetCapture() == this)
ReleaseCapture();
if (!_pressed)
return;
_pressed = false;
// Redraw the button immediately, before we trigger any actions
Invalidate();
UpdateWindow();
switch (GetButtonStyle()) {
case BS_PUSHBUTTON:
case BS_DEFPUSHBUTTON:
case BS_PUSHBOX:
case BS_OWNERDRAW:
SendMessage(BM_CLICK);
break;
case BS_CHECKBOX:
SetCheck(_itemState & BST_CHECKED ?
BST_CHECKED : BST_UNCHECKED);
SendMessage(BM_SETCHECK, _itemState & BST_CHECKED);
break;
case BS_AUTORADIOBUTTON:
SetCheck(BST_CHECKED);
SendMessage(BM_SETCHECK, BST_CHECKED);
break;
default:
error("Unhandled button type");
break;
}
}
void CButton::OnMouseMove(unsigned int nFlags, CPoint point) {
if (GetCapture() == this) {
if (_pressed != PointInClientRect(point)) {
_pressed = !_pressed;
Invalidate();
}
}
}
LRESULT CButton::OnBnClicked(WPARAM wParam, LPARAM lParam) {
GetParent()->SendMessage(WM_COMMAND, GetDlgCtrlID(),
MAKELPARAM(0, BN_CLICKED));
return 0;
}
LRESULT CButton::OnBnSetCheck(WPARAM wParam, LPARAM lParam) {
if (wParam == BST_UNCHECKED) {
// Uncheck the button
_itemState &= ~BST_CHECKED;
} else {
// Check the button
_itemState |= BST_CHECKED;
// Need to clear all of the others
CWnd *pParent = GetParent();
CWnd *pWnd = this;
for (;;) {
pWnd = pParent->GetNextDlgGroupItem(pWnd, true);
if (pWnd == this)
// No more to do
break;
pWnd->SendMessage(BM_SETCHECK, false);
}
}
Invalidate();
return 0;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,233 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
const AFX_MSGMAP *CCmdTarget::GetThisMessageMap() {
return nullptr;
}
void CCmdTarget::DoWaitCursor(int nCode) {
AfxGetApp()->DoWaitCursor(nCode);
}
void CCmdTarget::BeginWaitCursor() {
AfxGetApp()->DoWaitCursor(1);
}
void CCmdTarget::EndWaitCursor() {
AfxGetApp()->DoWaitCursor(-1);
}
void CCmdTarget::RestoreWaitCursor() {
AfxGetApp()->DoWaitCursor(0);
}
const AFX_MSGMAP_ENTRY *CCmdTarget::LookupMessage(unsigned int message) {
// Iterate through this class and any ancestors
for (const AFX_MSGMAP *map = GetMessageMap();
map; map = map->pfnGetBaseMap()) {
// Scan the entries to look for the message
for (const AFX_MSGMAP_ENTRY *entry = map->lpEntries;
entry->nMessage; ++entry) {
if (entry->nMessage == message)
return entry;
}
}
return nullptr;
}
bool CCmdTarget::OnCmdMsg(unsigned int nID, int nCode, void *pExtra,
AFX_CMDHANDLERINFO *pHandlerInfo) {
// Determine the message number and code (packed into nCode)
const AFX_MSGMAP *pMessageMap;
const AFX_MSGMAP_ENTRY *lpEntry;
unsigned int nMsg = 0;
if ((uint)nCode != CN_UPDATE_COMMAND_UI) {
nMsg = HIWORD(nCode);
nCode = LOWORD(nCode);
}
// For backward compatibility HIWORD(nCode)==0 is WM_COMMAND
if (nMsg == 0)
nMsg = WM_COMMAND;
// Look through message map to see if it applies to us
for (pMessageMap = GetMessageMap(); pMessageMap != nullptr;
pMessageMap = (*pMessageMap->pfnGetBaseMap)()) {
lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, nMsg, nCode, nID);
if (lpEntry) {
// found it
return _AfxDispatchCmdMsg(this, nID, nCode,
lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo);
}
}
// Not handled
return false;
}
const AFX_MSGMAP_ENTRY *CCmdTarget::AfxFindMessageEntry(const AFX_MSGMAP_ENTRY *lpEntry,
unsigned int nMsg, unsigned int nCode, unsigned int nID) {
while (lpEntry->nSig != AfxSig_end) {
if (lpEntry->nMessage == nMsg && lpEntry->nCode == nCode &&
nID >= lpEntry->nID && nID <= lpEntry->nLastID) {
return lpEntry;
}
lpEntry++;
}
return nullptr;
}
bool CCmdTarget::_AfxDispatchCmdMsg(CCmdTarget *pTarget, unsigned int nID, int nCode,
AFX_PMSG pfn, void *pExtra, unsigned int nSig, AFX_CMDHANDLERINFO *pHandlerInfo) {
union MessageMapFunctions mmf;
mmf.pfn = pfn;
bool bResult = true; // default is ok
if (pHandlerInfo != nullptr) {
// just fill in the information, don't do it
pHandlerInfo->pTarget = pTarget;
pHandlerInfo->pmf = mmf.pfn;
return true;
}
switch (nSig) {
case AfxSig_vv:
case AfxSigCmd_v:
// normal command or control notification
assert(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
assert(pExtra == nullptr);
(pTarget->*mmf.pfn_COMMAND)();
break;
case AfxSig_bv:
// Normal command or control notification
assert(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
assert(pExtra == nullptr);
bResult = (pTarget->*mmf.pfn_bCOMMAND)();
break;
case AfxSig_vw:
// Normal command or control notification in a range
assert(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
assert(pExtra == nullptr);
(pTarget->*mmf.pfn_COMMAND_RANGE)(nID);
break;
case AfxSig_bw:
// extended command (passed ID, returns bContinue)
assert(pExtra == nullptr);
bResult = (pTarget->*mmf.pfn_COMMAND_EX)(nID);
break;
case AfxSig_vNMHDRpl: {
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
assert(pNotify != nullptr);
assert(pNotify->pResult != nullptr);
assert(pNotify->pNMHDR != nullptr);
(pTarget->*mmf.pfn_NOTIFY)(pNotify->pNMHDR, pNotify->pResult);
}
break;
case AfxSig_bNMHDRpl: {
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
assert(pNotify != nullptr);
assert(pNotify->pResult != nullptr);
assert(pNotify->pNMHDR != nullptr);
bResult = (pTarget->*mmf.pfn_bNOTIFY)(pNotify->pNMHDR, pNotify->pResult);
}
break;
case AfxSig_vwNMHDRpl: {
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
assert(pNotify != nullptr);
assert(pNotify->pResult != nullptr);
assert(pNotify->pNMHDR != nullptr);
(pTarget->*mmf.pfn_NOTIFY_RANGE)(nID, pNotify->pNMHDR,
pNotify->pResult);
}
break;
case AfxSig_bwNMHDRpl: {
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
assert(pNotify != nullptr);
assert(pNotify->pResult != nullptr);
assert(pNotify->pNMHDR != nullptr);
bResult = (pTarget->*mmf.pfn_NOTIFY_EX)(nID, pNotify->pNMHDR,
pNotify->pResult);
}
break;
case AfxSig_cmdui: {
// ON_UPDATE_COMMAND_UI or ON_UPDATE_COMMAND_UI_REFLECT case
assert(CN_UPDATE_COMMAND_UI == (unsigned int)-1);
assert((uint)nCode == CN_UPDATE_COMMAND_UI || nCode == 0xFFFF);
assert(pExtra != nullptr);
CCmdUI *pCmdUI = (CCmdUI *)pExtra;
assert(!pCmdUI->m_bContinueRouting); // idle - not set
(pTarget->*mmf.pfn_UPDATE_COMMAND_UI)(pCmdUI);
bResult = !pCmdUI->m_bContinueRouting;
pCmdUI->m_bContinueRouting = false; // go back to idle
}
break;
case AfxSig_cmduiw: {
// ON_UPDATE_COMMAND_UI case
assert((uint)nCode == CN_UPDATE_COMMAND_UI);
assert(pExtra != nullptr);
CCmdUI *pCmdUI = (CCmdUI *)pExtra;
assert(pCmdUI->m_nID == (int)nID); // sanity assert
assert(!pCmdUI->m_bContinueRouting); // idle - not set
(pTarget->*mmf.pfn_UPDATE_COMMAND_UI_RANGE)(pCmdUI, nID);
bResult = !pCmdUI->m_bContinueRouting;
pCmdUI->m_bContinueRouting = false; // go back to idle
}
break;
// general extensibility hooks
case AfxSig_vpv:
(pTarget->*mmf.pfn_OTHER)(pExtra);
break;
case AfxSig_bpv:
bResult = (pTarget->*mmf.pfn_OTHER_EX)(pExtra);
break;
default:
// Illegal
error("Invalid sig");
}
return bResult;
}
} // namespace MFC
} // namespace Bagel

1388
engines/bagel/mfc/dc.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,415 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/keyboard.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CDialog, CWnd)
BEGIN_MESSAGE_MAP(CDialog, CWnd)
ON_COMMAND(IDOK, CDialog::OnOK)
ON_COMMAND(IDCANCEL, CDialog::OnCancel)
ON_MESSAGE(WM_INITDIALOG, CDialog::HandleInitDialog)
ON_MESSAGE(WM_SETFONT, CDialog::HandleSetFont)
ON_WM_SYSCHAR()
ON_WM_CLOSE()
ON_WM_ACTIVATE()
END_MESSAGE_MAP()
CDialog::CDialog(const char *lpszTemplateName, CWnd *pParentWnd) {
SetParent(pParentWnd);
m_lpszTemplateName = lpszTemplateName;
if (HIWORD(m_lpszTemplateName) == 0)
m_nIDHelp = LOWORD(m_lpszTemplateName);
}
CDialog::CDialog(unsigned int nIDTemplate, CWnd *pParentWnd) {
SetParent(pParentWnd);
m_lpszTemplateName = MAKEINTRESOURCE(nIDTemplate);
m_nIDHelp = nIDTemplate;
}
bool CDialog::Create(const char *lpszTemplateName,
CWnd *pParentWnd) {
m_lpszTemplateName = lpszTemplateName; // used for help
SetParent(pParentWnd);
if (HIWORD(m_lpszTemplateName) == 0 && m_nIDHelp == 0)
m_nIDHelp = LOWORD(m_lpszTemplateName);
HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG);
HRSRC hResource = FindResource(hInst, lpszTemplateName, RT_DIALOG);
HGLOBAL hTemplate = LoadResource(hInst, hResource);
bool bResult = CreateIndirect(hTemplate, m_pParentWnd, hInst);
FreeResource(hTemplate);
return bResult;
}
bool CDialog::Create(unsigned int nIDTemplate, CWnd *pParentWnd) {
return Create(MAKEINTRESOURCE(nIDTemplate), pParentWnd);
}
int CDialog::DoModal() {
// can be constructed with a resource template or InitModalIndirect
assert(m_lpszTemplateName != nullptr || m_hDialogTemplate != nullptr ||
m_lpDialogTemplate != nullptr);
// Save the prior focus, if any
CWnd *oldWin = AfxGetApp()->GetActiveWindow();
CWnd *oldFocus = GetFocus();
if (oldFocus)
AfxGetApp()->SetFocus(nullptr);
// load resource as necessary
LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;
HGLOBAL hDialogTemplate = m_hDialogTemplate;
HINSTANCE hInst = AfxGetResourceHandle();
if (m_lpszTemplateName != nullptr) {
hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
HRSRC hResource = FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
assert(hResource);
hDialogTemplate = LoadResource(hInst, hResource);
}
// Set up pointer to template data
if (hDialogTemplate != nullptr)
lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);
// Ensure the template is presenet
if (lpDialogTemplate == nullptr)
return -1;
// Set the dialog parent to be the app window
if (!m_pParentWnd)
m_pParentWnd = AfxGetApp()->m_pMainWnd;
if (CreateDlgIndirect(lpDialogTemplate,
this /*m_pParentWnd*/, hInst)) {
AfxGetApp()->doModal(this);
}
// Finish the dialog
PostModal();
// unlock/free resources as necessary
if (m_lpszTemplateName != NULL || m_hDialogTemplate != NULL)
UnlockResource(hDialogTemplate);
if (m_lpszTemplateName != NULL)
FreeResource(hDialogTemplate);
// Restore any old focus
if (oldFocus && AfxGetApp()->GetActiveWindow() == oldWin)
oldFocus->SetFocus();
if (_modalResult == DEFAULT_MODAL_RESULT)
_modalResult = -1;
return _modalResult;
}
bool CDialog::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate,
CWnd *pParentWnd, HINSTANCE hInst) {
assert(lpDialogTemplate != nullptr);
if (hInst == nullptr)
hInst = AfxGetInstanceHandle();
HGLOBAL hTemplate = nullptr;
#if 0
// If no font specified, set the system font.
CString strFace;
uint16 wSize = 0;
bool bSetSysFont = !CDialogTemplate::GetFont(lpDialogTemplate, strFace,
wSize);
if (bSetSysFont) {
CDialogTemplate dlgTemp(lpDialogTemplate);
dlgTemp.SetSystemFont(wSize);
hTemplate = dlgTemp.Detach();
}
#endif
if (hTemplate != nullptr)
lpDialogTemplate = (LPDLGTEMPLATE)GlobalLock(hTemplate);
// setup for modal loop and creation
_modalResult = DEFAULT_MODAL_RESULT;
m_nFlags |= WF_CONTINUEMODAL;
// Create modeless dialog
createDialogIndirect(lpDialogTemplate);
if (hTemplate != nullptr) {
GlobalUnlock(hTemplate);
GlobalFree(hTemplate);
}
return true;
}
void CDialog::SetParent(CWnd *wnd) {
m_pParentWnd = wnd;
}
uint32 CDialog::GetDefID() const {
return _defaultId;
}
void CDialog::SetDefID(unsigned int nID) {
CWnd *oldBtn;
if (_defaultId && (oldBtn = GetDlgItem(_defaultId)) != nullptr) {
uint32 style = oldBtn->GetStyle();
if ((style & 0xf) != BS_OWNERDRAW) {
style &= ~BS_DEFPUSHBUTTON;
oldBtn->SetStyle(style);
}
}
_defaultId = nID;
// Set new default
CWnd *newBtn = GetDlgItem(nID);
if (newBtn) {
uint32 style = newBtn->GetStyle();
if ((style & 0xf) != BS_OWNERDRAW) {
style = (style & ~0xF) | BS_DEFPUSHBUTTON;
newBtn->SetStyle(style);
}
}
}
LRESULT CDialog::HandleInitDialog(WPARAM, LPARAM) {
PreInitDialog();
OnInitDialog();
return 0;
}
LRESULT CDialog::HandleSetFont(WPARAM wParam, LPARAM) {
// Allow the CWnd code to set the _hFont field
CWnd::OnSetFont((HFONT)wParam, true);
// Virtual method dialog descendants can override
OnSetFont(CFont::FromHandle((HFONT)wParam));
return 0;
}
CButton *CDialog::GetDefaultPushButton() const {
for (auto &child : _children) {
CButton *pChild = dynamic_cast<CButton *>(child._value);
if (pChild) {
uint32 style = pChild->GetStyle();
if ((style & BS_DEFPUSHBUTTON) && pChild->GetDlgCtrlID() == IDOK) {
return pChild;
}
}
}
return nullptr;
}
void CDialog::DDX_Control(CDataExchange *pDX, int nIDC, CWnd &rControl) {
rControl.SubclassDlgItem(nIDC, this);
}
void CDialog::DDX_Radio(CDataExchange *pDX,
int nIDCButton1, int &value) {
error("TODO: CDialog::DDX_Radio");
}
void CDialog::DDX_Text(CDataExchange *pDX, int nIDC, int &value) {
error("TODO: CDialog::DDX_Text");
}
void CDialog::DDX_Text(CDataExchange *pDX, int nIDC, CString &value) {
CEdit *edit = dynamic_cast<CEdit *>(GetDlgItem(nIDC));
assert(edit);
if (pDX->m_bSaveAndValidate) {
edit->GetWindowText(value);
} else {
edit->SetWindowText(value.c_str());
}
}
void CDialog::DDX_Text(CDataExchange *pDX, int nIDC, unsigned int &value) {
error("TODO: CDialog::DDX_Text");
}
void CDialog::DDX_Text(CDataExchange *pDX, int nIDC, long &value) {
error("TODO: CDialog::DDX_Text");
}
void CDialog::DDX_Text(CDataExchange *pDX, int nIDC, double &value) {
error("TODO: CDialog::DDX_Text");
}
void CDialog::DDX_Check(CDataExchange *pDX,
int nIDC, bool value) {
error("CDialog::DDX_Check");
}
void CDialog::DDV_MinMaxInt(CDataExchange *pDX,
int value, int nMin, int nMax) {
error("TODO: CDialog::DDV_MinMaxInt");
}
void CDialog::EndDialog(int nResult) {
_modalResult = nResult;
}
bool CDialog::UpdateData(bool bSaveAndValidate) {
if (bSaveAndValidate) {
CDataExchange exchange = { true };
DoDataExchange(&exchange);
}
return true;
}
void CDialog::OnOK() {
if (!UpdateData(true))
return;
EndDialog(IDOK);
}
void CDialog::OnCancel() {
EndDialog(IDCANCEL);
}
bool CDialog::CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate,
CWnd *pParentWnd, void *lpDialogInit, HINSTANCE hInst) {
error("TODO: CDialog::CreateIndirect");
}
bool CDialog::CreateIndirect(HGLOBAL hDialogTemplate,
CWnd *pParentWnd, HINSTANCE hInst) {
error("TODO: CDialog::CreateIndirect");
}
void CDialog::OnSysChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {
// Convert input character to uppercase for case-insensitive match
char pressedChar = toupper(nChar);
for (auto &child : _children) {
CWnd *pChild = child._value;
CString text;
pChild->GetWindowText(text);
// Check for ampersand for hotkey underlining
uint idx = text.findFirstOf('&');
if (idx != Common::String::npos &&
pressedChar == toupper(text[idx + 1])) {
// Found match - simulate button click
pChild->SendMessage(BM_CLICK);
return;
}
}
// If no match found, pass to base class
CWnd::OnSysChar(nChar, nRepCnt, nFlags);
}
void CDialog::OnActivate(unsigned int nState, CWnd *pWndOther, bool bMinimized) {
if (nState != WA_INACTIVE) {
// Invalidate the dialog and its children
Invalidate(true);
for (auto child : _children)
child._value->Invalidate(true);
}
CWnd::OnActivate(nState, pWndOther, bMinimized);
}
bool CDialog::IsDialogMessage(LPMSG lpMsg) {
if (lpMsg->message != WM_KEYDOWN)
return false;
switch (lpMsg->wParam) {
case VK_RETURN:
return handleEnterKey(lpMsg);
case VK_ESCAPE:
return handleEscapeKey(lpMsg);
default:
break;
}
return false;
}
bool CDialog::handleEnterKey(LPMSG lpMsg) {
HWND hFocus = GetFocus();
if (!hFocus)
return false;
// Ask control what it wants
LRESULT dlgCode = MFC::SendMessage(hFocus, WM_GETDLGCODE,
lpMsg->wParam, (LPARAM)lpMsg);
// If control wants Enter, do nothing
if (dlgCode & DLGC_WANTMESSAGE)
return false;
// Multiline edits implicitly want Enter
if (dlgCode & DLGC_HASSETSEL)
return false;
// Find default push button
CButton *pDefault = GetDefaultPushButton();
if (!pDefault)
return false;
if (!pDefault->IsWindowEnabled())
// consume Enter, do nothing
return true;
// Simulate button click
sendButtonClicked(pDefault);
return true;
}
bool CDialog::handleEscapeKey(LPMSG lpMsg) {
CButton *pCancel = dynamic_cast<CButton *>(GetDlgItem(IDCANCEL));
if (!pCancel || !pCancel->IsWindowEnabled())
return true;
sendButtonClicked(pCancel);
return true;
}
void CDialog::sendButtonClicked(CButton *btn) {
int id = btn->GetDlgCtrlID();
SendMessage(WM_COMMAND, MAKEWPARAM(id, BN_CLICKED), (LPARAM)btn->m_hWnd);
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,69 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
void CDocManager::AddDocTemplate(CDocTemplate *pTemplate) {
if (pTemplate == nullptr) {
for (auto it = pStaticList.begin(); it != pStaticList.end(); ++it) {
CDocTemplate *tmp = *it;
AddDocTemplate(tmp);
}
pStaticList.clear();
bStaticInit = false;
} else {
ASSERT_VALID(pTemplate);
assert(!m_templateList.contains(pTemplate));
pTemplate->LoadTemplate();
m_templateList.push_back(pTemplate);
}
}
void CDocManager::OnFileNew() {
assert(!m_templateList.empty());
// ScummVM doesn't support more than 1 template
assert(m_templateList.size() == 1);
CDocTemplate *pTemplate = m_templateList.front();
ASSERT_KINDOF(CDocTemplate, pTemplate);
pTemplate->OpenDocumentFile(nullptr);
}
void CDocManager::OnFileOpen() {
error("TODO: CDocManager::onFileOpen");
}
void CDocManager::CloseAllDocuments(bool bEndSession) {
for (auto it = m_templateList.begin(); it != m_templateList.end(); ++it) {
CDocTemplate *pTemplate = *it;
ASSERT_KINDOF(CDocTemplate, pTemplate);
pTemplate->CloseAllDocuments(bEndSession);
}
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,128 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CDocTemplate, CCmdTarget)
BEGIN_MESSAGE_MAP(CDocTemplate, CCmdTarget)
END_MESSAGE_MAP()
CDocTemplate::CDocTemplate(unsigned int nIDResource, const CRuntimeClass *pDocClass,
const CRuntimeClass *pFrameClass, const CRuntimeClass *pViewClass) {
assert(nIDResource != 0);
ASSERT(pDocClass == nullptr ||
pDocClass->IsDerivedFrom(RUNTIME_CLASS(CDocument)));
ASSERT(pFrameClass == nullptr ||
pFrameClass->IsDerivedFrom(RUNTIME_CLASS(CFrameWnd)));
ASSERT(pViewClass == nullptr ||
pViewClass->IsDerivedFrom(RUNTIME_CLASS(CView)));
m_nIDResource = nIDResource;
m_pDocClass = pDocClass;
m_pFrameClass = pFrameClass;
m_pViewClass = pViewClass;
}
CDocument *CDocTemplate::CreateNewDocument() {
assert(m_pDocClass);
CDocument *pDocument = (CDocument *)m_pDocClass->CreateObject();
assert(pDocument);
ASSERT_KINDOF(CDocument, pDocument);
AddDocument(pDocument);
return pDocument;
}
void CDocTemplate::AddDocument(CDocument *pDoc) {
ASSERT_VALID(pDoc);
assert(pDoc->m_pDocTemplate == nullptr); // no template attached yet
pDoc->m_pDocTemplate = this;
}
void CDocTemplate::RemoveDocument(CDocument *pDoc) {
ASSERT_VALID(pDoc);
assert(pDoc->m_pDocTemplate == this); // must be attached to us
pDoc->m_pDocTemplate = nullptr;
}
CFrameWnd *CDocTemplate::CreateNewFrame(CDocument *pDoc, CFrameWnd *pOther) {
if (pDoc != nullptr)
ASSERT_VALID(pDoc);
// Create a frame wired to the specified document
// Must have a resource ID to load from
assert(m_nIDResource != 0);
CCreateContext context;
context.m_pCurrentFrame = pOther;
context.m_pCurrentDoc = pDoc;
context.m_pNewViewClass = m_pViewClass;
context.m_pNewDocTemplate = this;
assert(m_pFrameClass);
CFrameWnd *pFrame = (CFrameWnd *)m_pFrameClass->CreateObject();
assert(pFrame);
ASSERT_KINDOF(CFrameWnd, pFrame);
assert(context.m_pNewViewClass);
// Create new from resource
if (!pFrame->LoadFrame(m_nIDResource,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
nullptr, &context))
{
warning("CDocTemplate couldn't create a frame.");
// frame will be deleted in PostNcDestroy cleanup
return nullptr;
}
return pFrame;
}
void CDocTemplate::InitialUpdateFrame(CFrameWnd *pFrame, CDocument *pDoc,
bool bMakeVisible) {
// Just delagate to implementation in CFrameWnd
pFrame->InitialUpdateFrame(pDoc, bMakeVisible);
}
void CDocTemplate::LoadTemplate() {
if (m_strDocStrings.IsEmpty() && !m_strDocStrings.LoadString(m_nIDResource)) {
warning("No document names in string for template #%d.",
m_nIDResource);
}
// TODO: If needed, menus and accelerators
}
void CDocTemplate::CloseAllDocuments(bool) {
POSITION pos = GetFirstDocPosition();
while (pos != NULL)
{
CDocument *pDoc = GetNextDoc(pos);
pDoc->OnCloseDocument();
}
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,170 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CDocument, CCmdTarget)
BEGIN_MESSAGE_MAP(CDocument, CCmdTarget)
END_MESSAGE_MAP()
const CString &CDocument::GetTitle() const {
return _title;
}
void CDocument::SetTitle(const char *lpszTitle) {
_title = CString(lpszTitle);
}
const CString &CDocument::GetPathName() const {
return _unusedPathName;
}
void CDocument::SetPathName(const char *lpszPathName, bool bAddToMRU) {
}
void CDocument::ClearPathName() {
}
bool CDocument::IsModified() {
return m_bModified;
}
void CDocument::SetModifiedFlag(bool bModified) {
m_bModified = bModified;
}
void CDocument::AddView(CView *pView) {
assert(dynamic_cast<CView *>(pView) != nullptr);
assert(pView->m_pDocument == nullptr); // must not be already attached
assert(!m_viewList.contains(pView)); // must not be in list
m_viewList.push_back(pView);
assert(pView->m_pDocument == nullptr); // must be un-attached
pView->m_pDocument = this;
OnChangedViewList(); // must be the last thing done to the document
}
void CDocument::RemoveView(CView *pView) {
ASSERT_VALID(pView);
assert(pView->m_pDocument == this); // Must be attached to us
m_viewList.remove(pView);
pView->m_pDocument = nullptr;
// Must be the last thing done to the document
OnChangedViewList();
}
void CDocument::DeleteContents() {
}
void CDocument::ReportSaveLoadException(const char *lpszPathName,
CException *e, bool bSaving, unsigned int nIDPDefault) {
error("Save/load error");
}
void CDocument::UpdateAllViews(CView *pSender, LPARAM lHint,
CObject *pHint) {
assert(pSender == nullptr || !m_viewList.empty());
for (ViewArray::iterator pos = m_viewList.begin();
pos != m_viewList.end(); ++pos) {
CView *pView = *pos;
if (pView != pSender)
pView->OnUpdate(pSender, lHint, pHint);
}
}
POSITION CDocument::GetFirstViewPosition() {
return m_viewList.empty() ? nullptr :
(POSITION)& m_viewList[0];
}
CView *CDocument::GetNextView(POSITION &rPosition) const {
if (rPosition == nullptr)
return nullptr;
CView **&rPos = reinterpret_cast<CView **&>(rPosition);
const CView *const *rEnd = &m_viewList[0] + m_viewList.size();
if (rPos >= rEnd)
return nullptr;
return *rPos++;
}
bool CDocument::SaveModified() {
// TODO: CDocument::SaveModified
return true;
}
void CDocument::OnCloseDocument() {
// Destroy all frames viewing this document
// the last destroy may destroy us
bool bAutoDelete = m_bAutoDelete;
m_bAutoDelete = false; // don't destroy document while closing views
while (!m_viewList.empty()) {
size_t arrSize = m_viewList.size();
// get frame attached to the view
CView *pView = m_viewList.front();
ASSERT_VALID(pView);
CFrameWnd *pFrame = pView->GetParentFrame();
ASSERT_VALID(pFrame);
// and close it
PreCloseFrame(pFrame);
pFrame->DestroyWindow();
// will destroy the view as well
assert(m_viewList.size() < arrSize);
}
m_bAutoDelete = bAutoDelete;
// clean up contents of document before destroying the document itself
DeleteContents();
// delete the document if necessary
if (m_bAutoDelete)
delete this;
}
void CDocument::OnChangedViewList() {
// if no more views on the document, delete ourself
// not called if directly closing the document or terminating the app
if (m_viewList.empty() && m_bAutoDelete) {
OnCloseDocument();
return;
}
// update the frame counts as needed
UpdateFrameCounts();
}
} // namespace MFC
} // namespace Bagel

155
engines/bagel/mfc/edit.cpp Normal file
View File

@@ -0,0 +1,155 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
#define TIMER_ID 1
IMPLEMENT_DYNAMIC(CEdit, CWnd)
BEGIN_MESSAGE_MAP(CEdit, CWnd)
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_CHAR()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_TIMER()
ON_WM_GETDLGCODE()
END_MESSAGE_MAP()
bool CEdit::Create(uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID) {
return CWnd::Create("EDIT", nullptr, dwStyle,
rect, pParentWnd, nID);
}
void CEdit::LimitText(int nChars) {
_maxLength = nChars;
}
void CEdit::SetSel(int nStartChar, int nEndChar, bool bNoScroll) {
warning("TODO: CEdit::SetSel");
}
void CEdit::OnPaint() {
CPaintDC dc(this); // Automatically calls BeginPaint and EndPaint
// Get client area
CRect clientRect;
GetClientRect(&clientRect);
// Fill background with system window color
HBRUSH hBrush = MFC::GetSysColorBrush(COLOR_WINDOW);
CBrush *winBrush = CBrush::FromHandle(hBrush);
dc.FillRect(&clientRect, winBrush);
// Set text and background properties
dc.SetTextColor(MFC::GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkMode(TRANSPARENT);
// Select the current font if one was set
HFONT hFont = (HFONT)SendMessage(WM_GETFONT);
HFONT hOldFont = nullptr;
if (hFont)
hOldFont = (HFONT)dc.SelectObject(hFont);
// Draw the stored text
dc.DrawText(_windowText.c_str(), -1, &clientRect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
// If needed, draw the caret
if (_cursorVisible) {
CSize size = dc.GetTextExtent(_windowText.c_str(), -1);
CPen caretPen(PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT));
CPen *pOldPen = dc.SelectObject(&caretPen);
// Draw the caret (as a vertical line or filled rectangle)
#if 0
CBrush *pOldBrush = static_cast<CBrush *>(dc.SelectStockObject(NULL_BRUSH));
CRect caretRect(size.cx + 2, 2, size.cx + 4, clientRect.bottom - 2);
dc.Rectangle(&caretRect);
#endif
dc.MoveTo(size.cx + 3, 2);
dc.LineTo(size.cx + 3, clientRect.bottom - 2);
// Restore old objects
dc.SelectObject(pOldPen);
// dc.SelectObject(pOldBrush);
}
// Restore font if changed
if (hFont)
dc.SelectObject(hOldFont);
}
void CEdit::OnKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {
if (nChar == Common::KEYCODE_BACKSPACE ||
nChar == Common::KEYCODE_DELETE) {
if (!_windowText.empty()) {
_windowText.deleteLastChar();
}
}
Invalidate();
}
void CEdit::OnChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {
if (Common::isPrint(nChar)) {
if (_maxLength == 0 || _windowText.size() < _maxLength) {
_windowText += (char)nChar;
Invalidate();
}
}
}
void CEdit::OnSetFocus(CWnd *pOldWnd) {
SetTimer(TIMER_ID, 500);
CWnd::OnSetFocus(pOldWnd);
}
void CEdit::OnKillFocus(CWnd *pNewWnd) {
KillTimer(TIMER_ID);
CWnd::OnKillFocus(pNewWnd);
if (_cursorVisible) {
_cursorVisible = false;
OnPaint();
}
}
void CEdit::OnTimer(uintptr nTimerId) {
_cursorVisible = !_cursorVisible;
Invalidate();
}
unsigned int CEdit::OnGetDlgCode() {
uint style = GetStyle();
if (style & ES_MULTILINE)
return DLGC_WANTMESSAGE | DLGC_HASSETSEL;
return 0;
}
} // namespace MFC
} // namespace Bagel

105
engines/bagel/mfc/file.cpp Normal file
View File

@@ -0,0 +1,105 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/file.h"
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CFile, CObject)
CFile::CFile(const char *lpszFileName, unsigned int nOpenFlags) {
if (!Open(lpszFileName, nOpenFlags))
error("Could not open - %s", lpszFileName);
}
bool CFile::Open(const char *lpszFileName, unsigned int nOpenFlags, CFileException *pError) {
Close();
Common::SeekableReadStream *rs = OpenFile(lpszFileName);
if (rs)
_stream = rs;
return rs != nullptr;
}
void CFile::Close() {
delete _stream;
_stream = nullptr;
}
void CFile::Abort() {
error("TODO: CFile::Abort");
}
Common::SeekableReadStream *CFile::readStream() const {
Common::SeekableReadStream *rs = dynamic_cast <
Common::SeekableReadStream * > (_stream);
assert(rs);
return rs;
}
Common::WriteStream *CFile::writeStream() const {
Common::WriteStream *ws = dynamic_cast <
Common::WriteStream * > (_stream);
assert(ws);
return ws;
}
uint64 CFile::SeekToEnd() {
return readStream()->seek(0, SEEK_END);
}
void CFile::SeekToBegin() {
readStream()->seek(0);
}
uint64 CFile::Seek(int64 lOff, unsigned int nFrom) {
return readStream()->seek(lOff, nFrom);
}
uint64 CFile::GetLength() const {
return readStream()->size();
}
uint64 CFile::GetPosition() const {
return readStream()->pos();
}
unsigned int CFile::Read(void *lpBuf, unsigned int nCount) {
return readStream()->read(lpBuf, nCount);
}
void CFile::Write(const void *lpBuf, unsigned int nCount) {
writeStream()->write(lpBuf, nCount);
}
Common::SeekableReadStream *CFile::detach() {
Common::SeekableReadStream *result = readStream();
_stream = nullptr;
return result;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,59 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
bool CFont::CreateFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, byte bItalic, byte bUnderline,
byte cStrikeOut, byte nCharSet, byte nOutPrecision,
byte nClipPrecision, byte nQuality, byte nPitchAndFamily,
const char *lpszFacename) {
m_hObject = AfxGetApp()->createFont(nHeight, nWidth,
nEscapement, nOrientation, nWeight, bItalic,
bUnderline, cStrikeOut, nCharSet, nOutPrecision,
nClipPrecision, nQuality, nPitchAndFamily,
lpszFacename);
assert(m_hObject);
// This is where it becomes permanent
AfxHookObject();
return true;
}
bool CFont::CreateFontIndirect(const LOGFONT *lpLogFont) {
assert(lpLogFont != nullptr);
m_hObject = MFC::CreateFontIndirect(lpLogFont);
if (m_hObject == nullptr)
return false;
// This is where it becomes permanent
AfxHookObject();
return true;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,255 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CFrameWnd, CWnd)
BEGIN_MESSAGE_MAP(CFrameWnd, CWnd)
ON_WM_CREATE()
ON_WM_ACTIVATE()
END_MESSAGE_MAP()
HMENU CFrameWnd::GetMenu() const {
return nullptr;
}
void CFrameWnd::RecalcLayout(bool bNotify) {
// No implementation in ScummVM
}
bool CFrameWnd::RepositionBars(unsigned int nIDFirst, unsigned int nIDLast,
unsigned int nIDLeftOver, unsigned int nFlag, LPRECT lpRectParam,
LPCRECT lpRectClient, bool bStretch) {
error("TODO: CFrameWnd::RepositionBars");
}
void CFrameWnd::InitialUpdateFrame(CDocument *pDoc, bool bMakeVisible) {
// if the frame does not have an active view, set to first pane
CView *pView = nullptr;
if (GetActiveView() == nullptr) {
CWnd *pWnd = _children.empty() ? nullptr :
_children.begin()->_value;
if (pWnd != nullptr && pWnd->IsKindOf(RUNTIME_CLASS(CView))) {
pView = (CView *)pWnd;
SetActiveView(pView, false);
}
}
if (bMakeVisible) {
// send initial update to all views (and other controls) in the frame
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, true, true);
// give view a chance to save the focus (CFormView needs this)
if (pView != nullptr)
pView->OnActivateFrame(WA_INACTIVE, this);
// finally, activate the frame
// (send the default show command unless the main desktop window)
int nCmdShow = -1; // default
CWinApp *pApp = AfxGetApp();
if (pApp != nullptr && pApp->m_pMainWnd == this) {
nCmdShow = pApp->m_nCmdShow; // use the parameter from WinMain
pApp->m_nCmdShow = -1; // set to default after first time
}
ActivateFrame(nCmdShow);
if (pView != nullptr)
pView->OnActivateView(true, pView, pView);
}
// update frame counts and frame title (may already have been visible)
if (pDoc != nullptr)
pDoc->UpdateFrameCounts();
OnUpdateFrameTitle(true);
}
bool CFrameWnd::LoadFrame(unsigned int nIDResource, uint32 dwDefaultStyle,
CWnd *pParentWnd, CCreateContext *pContext) {
assert(m_nIDHelp == 0 || m_nIDHelp == nIDResource);
m_nIDHelp = nIDResource; // ID for help context (+HID_BASE_RESOURCE)
CString strFullString;
if (strFullString.LoadString(nIDResource))
AfxExtractSubString(m_strTitle, strFullString, 0); // first sub-string
//VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
// Create the window
const char *lpszClass = nullptr; //GetIconWndClass(dwDefaultStyle, nIDResource);
const char *lpszTitle = m_strTitle.c_str();
CRect rectDefault;
if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault,
pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext)) {
return false; // will self destruct on failure normally
}
ASSERT(m_hWnd != nullptr);
// TODO: Menu and accelerators if needed
if (pContext == nullptr) // send initial update
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, true, true);
return true;
}
bool CFrameWnd::Create(const char *lpszClassName,
const char *lpszWindowName, uint32 dwStyle,
const RECT &rect, CWnd *pParentWnd,
const char *lpszMenuName, uint32 dwExStyle,
CCreateContext *pContext) {
HMENU hMenu = nullptr;
if (lpszMenuName != nullptr) {
// TODO: Menu loading if needed
}
m_strTitle = lpszWindowName; // Save title for later
if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
pParentWnd ? pParentWnd->GetSafeHwnd() : 0,
(LPARAM)hMenu, pContext)) {
warning("failed to create CFrameWnd.");
if (hMenu != nullptr)
DestroyMenu(hMenu);
return false;
}
return true;
}
int CFrameWnd::OnCreate(LPCREATESTRUCT lpcs) {
CCreateContext *pContext = (CCreateContext *)lpcs->lpCreateParams;
return OnCreateHelper(lpcs, pContext);
}
int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext *pContext) {
if (CWnd::OnCreate(lpcs) == -1)
return -1;
// Create the client view, if any
if (!OnCreateClient(lpcs, pContext)) {
warning("Failed to create client pane/view for frame.\n");
return -1;
}
RecalcLayout();
return 0;
}
bool CFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext) {
if (pContext != nullptr && pContext->m_pNewViewClass != nullptr) {
if (CreateView(pContext, AFX_IDW_PANE_FIRST) == nullptr)
return false;
}
return true;
}
CWnd *CFrameWnd::CreateView(CCreateContext *pContext, unsigned int nID) {
assert(m_hWnd != nullptr);
assert(pContext != nullptr);
assert(pContext->m_pNewViewClass != nullptr);
CWnd *pView = (CWnd *)pContext->m_pNewViewClass->CreateObject();
assert(pView);
ASSERT_KINDOF(CWnd, pView);
if (!pView->Create(nullptr, nullptr, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, nID, pContext)) {
return nullptr; // can't continue without a view
}
return pView;
}
CView *CFrameWnd::GetActiveView() const {
ASSERT(m_pViewActive == nullptr ||
m_pViewActive->IsKindOf(RUNTIME_CLASS(CView)));
return m_pViewActive;
}
void CFrameWnd::SetActiveView(CView *pViewNew, bool bNotify) {
CView *pViewOld = m_pViewActive;
if (pViewNew == pViewOld)
return; // do not re-activate if SetActiveView called more than once
m_pViewActive = nullptr; // no active for the following processing
// deactivate the old one
if (pViewOld != nullptr)
pViewOld->OnActivateView(false, pViewNew, pViewOld);
// if the OnActivateView moves the active window,
// that will veto this change
if (m_pViewActive != nullptr)
return; // already set
m_pViewActive = pViewNew;
// activate
if (pViewNew != nullptr && bNotify)
pViewNew->OnActivateView(true, pViewNew, pViewOld);
}
void CFrameWnd::OnSetFocus(CWnd *pOldWnd) {
if (m_pViewActive != nullptr)
m_pViewActive->SetFocus();
else
CWnd::OnSetFocus(pOldWnd);
}
CDocument *CFrameWnd::GetActiveDocument() {
ASSERT_VALID(this);
CView *pView = GetActiveView();
if (pView != nullptr)
return pView->GetDocument();
return nullptr;
}
void CFrameWnd::ActivateFrame(int nCmdShow) {
// TODO: CFrameWnd::ActivateFrame
}
void CFrameWnd::OnUpdateFrameTitle(bool bAddToTitle) {
// TODO: CFrameWnd::OnUpdateFrameTitle
}
void CFrameWnd::OnActivate(unsigned int nState, CWnd *pWndOther, bool bMinimized) {
if (nState != WA_INACTIVE) {
// Invalidate the dialog and its children
Invalidate(true);
for (auto child : _children)
child._value->Invalidate(true);
}
CWnd::OnActivate(nState, pWndOther, bMinimized);
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,97 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/win_hand.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNCREATE(CGdiObject, CObject)
CGdiObject::~CGdiObject() {
if (m_hObject && _permanent)
DeleteObject();
}
bool CGdiObject::Attach(HGDIOBJ hObject) {
// Detach any prior object
Detach();
// Attach new object
m_hObject = hObject;
AfxHookObject();
return true;
}
HGDIOBJ CGdiObject::Detach() {
HGDIOBJ result = m_hObject;
AfxUnhookObject();
return result;
}
bool CGdiObject::DeleteObject() {
AfxUnhookObject();
// Check added to ensure I don't accidentally
// delete the _defaultBitmap field of the CDC::Impl
assert(!dynamic_cast<CDC::DefaultBitmap *>(this));
delete m_hObject;
m_hObject = nullptr;
return true;
}
CGdiObject *CGdiObject::FromHandle(HGDIOBJ h) {
CHandleMap<CGdiObject> *pMap = AfxGetApp()->afxMapHGDIOBJ(true);
assert(pMap != nullptr);
CGdiObject *pObject = pMap->FromHandle(h);
assert(pObject == nullptr || pObject->m_hObject == h);
return pObject;
}
void CGdiObject::AfxHookObject() {
CHandleMap<CGdiObject> *pMap = AfxGetApp()->afxMapHGDIOBJ(true);
assert(pMap != nullptr);
if (!pMap->LookupPermanent(m_hObject)) {
pMap->SetPermanent(m_hObject, this);
_permanent = true;
}
}
void CGdiObject::AfxUnhookObject() {
if (m_hObject && _permanent) {
CHandleMap<CGdiObject> *pMap = AfxGetApp()->afxMapHGDIOBJ(true);
assert(pMap != nullptr);
pMap->RemoveHandle(m_hObject);
_permanent = false;
}
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,229 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/gfx/blitter.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
static inline void copyPixel(const byte *srcP, byte *destP, int mode, const byte &WHITE,
bool isDestMonochrome, uint bgColor, const uint32 *paletteMap) {
byte src = *srcP;
if (paletteMap)
src = paletteMap[src];
switch (mode) {
case SRCCOPY:
*destP = src;
break;
case SRCAND:
*destP &= src;
break;
case SRCINVERT:
*destP ^= src;
break;
case SRCPAINT:
*destP |= src;
break;
case NOTSRCCOPY:
if (isDestMonochrome) {
*destP = src == bgColor ? 0 : 0xff;
return;
}
*destP = ~src;
break;
case DSTINVERT:
*destP = ~*destP;
return;
case BLACKNESS:
*destP = 0;
return;
case WHITENESS:
*destP = WHITE;
return;
default:
error("Unsupported blit mode");
break;
}
if (isDestMonochrome)
*destP = *destP == bgColor ? 0xff : 0;
}
static void blitInner(Gfx::Surface *srcSurface,
Gfx::Surface *destSurface,
const Common::Rect &srcRect, const Common::Point &destPos,
uint bgColor, int mode, const uint32 *paletteMap) {
const bool isDestMonochrome = destSurface->format.bytesPerPixel == 1 &&
destSurface->format.aLoss == 255;
const byte WHITE = 255;
Surface::YIterator ySrc(srcSurface);
Surface::XIterator xSrc(&ySrc);
Surface::YIterator yDest(destSurface);
Surface::XIterator xDest(&yDest);
byte dummy = 0;
byte *srcP, *destP;
for (ySrc = srcRect.top, yDest = destPos.y; ySrc < srcRect.bottom; ++ySrc, ++yDest) {
for (xSrc = srcRect.left, xDest = destPos.x; xSrc < srcRect.right; ++xSrc, ++xDest) {
srcP = xSrc;
destP = xDest;
if (!srcP)
srcP = &dummy;
if (!destP)
destP = &dummy;
copyPixel(srcP, destP, mode, WHITE, isDestMonochrome, bgColor, paletteMap);
}
}
}
static void stretchBlitInner(Gfx::Surface *srcSurface,
Gfx::Surface *destSurface,
const Common::Rect &srcRect, const Common::Rect &dstRect,
uint bgColor, int mode, const uint32 *paletteMap) {
const bool isDestMonochrome = destSurface->format.bytesPerPixel == 1 &&
destSurface->format.aLoss == 255;
const byte WHITE = 255;
const int srcWidth = srcRect.right - srcRect.left;
const int srcHeight = srcRect.bottom - srcRect.top;
const int dstWidth = dstRect.right - dstRect.left;
const int dstHeight = dstRect.bottom - dstRect.top;
Surface::YIterator ySrc(srcSurface);
Surface::XIterator xSrc(&ySrc);
Surface::YIterator yDest(destSurface);
Surface::XIterator xDest(&yDest);
if (srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0)
return; // Invalid rectangles
for (int y = 0; y < dstHeight; ++y) {
// Map destination y to source y using fixed-point arithmetic
int srcY = srcRect.top + (y * srcHeight) / dstHeight;
if (srcY >= srcSurface->h)
continue;
int dstY = dstRect.top + y;
if (dstY >= destSurface->h)
continue;
for (int x = 0; x < dstWidth; ++x) {
int srcX = srcRect.left + (x * srcWidth) / dstWidth;
if (srcX >= srcSurface->w)
continue;
int dstX = dstRect.left + x;
if (dstX >= destSurface->w)
continue;
xSrc = srcX;
ySrc = srcY;
byte *srcP = xSrc;
xDest = dstX;
yDest = dstY;
byte *destP = xDest;
copyPixel(srcP, destP, mode, WHITE, isDestMonochrome, bgColor, paletteMap);
}
}
}
void blit(Gfx::Surface *src, Gfx::Surface *dest,
const Common::Rect &srcRect, const Common::Point &destPos,
uint bgColor, int mode, const uint32 *paletteMap) {
// For normal copying modes, the formats must match.
// Other modes like DSTINVERT don't need a source,
// so in that case the source can remain uninitialized
assert(src->format.bytesPerPixel == dest->format.bytesPerPixel ||
src->format.bytesPerPixel == 0);
assert(dest->format.bytesPerPixel == dest->format.bytesPerPixel ||
dest->format.bytesPerPixel == 0);
blitInner(src, dest, srcRect, destPos, bgColor, mode, paletteMap);
Common::Rect dirtyRect(destPos.x, destPos.y,
destPos.x + srcRect.width(), destPos.y + srcRect.height());
dest->addDirtyRect(dirtyRect);
}
void stretchBlit(Gfx::Surface *src, Gfx::Surface *dest,
const Common::Rect &srcRect, const Common::Rect &destRect,
uint bgColor, int mode, const uint32 *paletteMap) {
assert(src->format.bytesPerPixel == dest->format.bytesPerPixel ||
src->format.bytesPerPixel == 0);
assert(dest->format.bytesPerPixel == dest->format.bytesPerPixel ||
dest->format.bytesPerPixel == 0);
stretchBlitInner(src, dest, srcRect, destRect, bgColor, mode, paletteMap);
}
static inline void rasterPixel(byte *pixel, byte) {
// Currently only R2_NOT
*pixel = ~*pixel;
}
void frameRect(Gfx::Surface *dest,
const Common::Rect &r, byte color, int drawMode) {
assert(dest->format.bytesPerPixel == 1);
if (drawMode == R2_COPYPEN) {
dest->frameRect(r, color);
return;
} else if (drawMode == R2_NOP) {
return;
}
assert(drawMode == R2_NOT);
const int w = r.right - r.left;
const int h = r.bottom - r.top - 2;
byte *pixel;
// Top line
pixel = (byte *)dest->getBasePtr(r.left, r.top);
for (int x = 0; x < w; ++x, ++pixel)
rasterPixel(pixel, color);
// Bottom line
pixel = (byte *)dest->getBasePtr(r.left, r.bottom - 1);
for (int x = 0; x < w; ++x, ++pixel)
rasterPixel(pixel, color);
// Left edge
pixel = (byte *)dest->getBasePtr(r.left, r.top + 1);
for (int y = 0; y < h; ++y, pixel += dest->pitch)
rasterPixel(pixel, color);
// Right edge
pixel = (byte *)dest->getBasePtr(r.right - 1, r.top + 1);
for (int y = 0; y < h; ++y, pixel += dest->pitch)
rasterPixel(pixel, color);
// Mark the rectangle area as dirty
dest->addDirtyRect(r);
}
} // namespace Gfx
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,46 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GFX_BLITTER_H
#define BAGEL_MFC_GFX_BLITTER_H
#include "bagel/mfc/gfx/surface.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
extern void blit(Gfx::Surface *src, Gfx::Surface *dest,
const Common::Rect &srcRect, const Common::Point &destPos,
uint bgColor, int mode, const uint32 *paletteMap);
extern void stretchBlit(Gfx::Surface *src, Gfx::Surface *dest,
const Common::Rect &srcRect, const Common::Rect &destRect,
uint bgColor, int mode, const uint32 *paletteMap);
extern void frameRect(Gfx::Surface *dest,
const Common::Rect &r, byte color, int drawMode);
} // namespace Gfx
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,186 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "graphics/cursorman.h"
#include "graphics/wincursor.h"
#include "image/bmp.h"
#include "bagel/mfc/gfx/cursor.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
static const byte ARROW_CURSOR[CURSOR_W * CURSOR_H] = {
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0,
1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0,
1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0,
1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0,
1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 0, 0,
1, 2, 2, 1, 1, 2, 2, 1, 0, 0, 0, 0,
1, 2, 1, 0, 0, 1, 2, 2, 1, 0, 0, 0,
1, 1, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0,
1, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0,
0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0
};
static const byte HOURGLASS_CURSOR[CURSOR_W * CURSOR_H] = {
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0,
0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0,
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const byte CURSOR_PALETTE[9] = { 0x80, 0x80, 0x80, 0, 0, 0, 0xff, 0xff, 0xff };
/*--------------------------------------------*/
Cursors::Cursors(Libs::Resources &res) /* : _resources(res) */ {
_cursors[(intptr)IDC_ARROW] = new Cursor(ARROW_CURSOR);
_cursors[(intptr)IDC_WAIT] = new Cursor(HOURGLASS_CURSOR);
_arrowCursor = (HCURSOR)_cursors[(intptr)IDC_ARROW];
_waitCursor = (HCURSOR)_cursors[(intptr)IDC_WAIT];
}
Cursors::~Cursors() {
for (CursorHash::iterator it = _cursors.begin();
it != _cursors.end(); ++it)
delete it->_value;
}
HCURSOR Cursors::loadCursor(intptr cursorId) {
if (!cursorId)
// Null cursor used to hide cursor
return (HCURSOR)nullptr;
if (_cursors.contains(cursorId))
return (HCURSOR)_cursors[cursorId];
Cursor *c = new Cursor(cursorId);
_cursors[cursorId] = c;
return (HCURSOR)c;
}
/*--------------------------------------------*/
Cursor::Cursor(const byte *pixels) : _isBuiltIn(true) {
_surface.create(CURSOR_W, CURSOR_H,
Graphics::PixelFormat::createFormatCLUT8());
byte *dest = (byte *)_surface.getPixels();
Common::copy(pixels, pixels + CURSOR_W * CURSOR_H, dest);
}
Cursor::Cursor(intptr cursorId) : _isBuiltIn(false) {
Image::BitmapDecoder decoder;
const auto &resList = AfxGetApp()->getResources();
intptr id = cursorId;
bool success = false;
Common::SeekableReadStream *bmp = nullptr;
for (const auto &res : resList) {
bmp = res._res->getResource(
Common::kWinBitmap,
(id < 65536) ? Common::WinResourceID(id) :
Common::WinResourceID(cursorId));
if (bmp)
break;
}
if (bmp) {
success = decoder.loadStream(*bmp);
if (success) {
const Graphics::Surface &s = *decoder.getSurface();
_surface.copyFrom(s);
}
}
if (_surface.empty()) {
for (const auto &res : resList) {
_cursorGroup = Graphics::WinCursorGroup::createCursorGroup(res._res, id);
if (_cursorGroup) {
success = true;
break;
}
}
}
if (!success)
error("Could not load cursor resource");
}
Cursor::~Cursor() {
delete _cursorGroup;
}
void Cursor::showCursor() {
Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
CursorMan.disableCursorPalette(!_isBuiltIn);
if (_isBuiltIn)
CursorMan.replaceCursorPalette(CURSOR_PALETTE, 0, ARRAYSIZE(CURSOR_PALETTE) / 3);
if (_cursorGroup) {
const auto &cursor = _cursorGroup->cursors[0].cursor;
CursorMan.replaceCursor(cursor);
} else {
CursorMan.replaceCursor(_surface.getPixels(),
_surface.w, _surface.h, 0, 0, 0, true, &format);
}
CursorMan.showMouse(true);
}
void Cursor::hide() {
CursorMan.showMouse(false);
}
} // namespace Gfx
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,108 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GFX_CURSOR_H
#define BAGEL_MFC_GFX_CURSOR_H
#include "common/hash-str.h"
#include "common/path.h"
#include "common/formats/winexe_ne.h"
#include "graphics/managed_surface.h"
#include "graphics/wincursor.h"
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/libs/resources.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
constexpr int CURSOR_W = 12;
constexpr int CURSOR_H = 20;
struct ResourceString_Hash {
uint operator()(const intptr s) const {
return s <= 0xffff ? s : Common::hashit((const char *)s);
}
};
struct ResourceString_EqualTo {
bool operator()(const intptr x, const intptr y) const {
bool xNum = x <= 0xffff;
bool yNum = y <= 0xffff;
return (xNum == yNum) && (
(xNum && x == y) ||
(!xNum && !strcmp((const char *)x, (const char *)y))
);
}
};
class Cursor {
private:
Graphics::ManagedSurface _surface;
Graphics::WinCursorGroup *_cursorGroup = nullptr;
bool _isBuiltIn = false;
public:
static void hide();
public:
/**
* Constructor for predefined cursors
*/
Cursor(const byte *pixels);
/**
* Constructor for cursor resources
*/
Cursor(intptr cursorId);
~Cursor();
/**
* Set the cursor to be active
*/
void showCursor();
};
class Cursors {
private:
//Libs::Resources &_resources;
typedef Common::HashMap<intptr, Cursor *,
ResourceString_Hash, ResourceString_EqualTo> CursorHash;
CursorHash _cursors;
public:
HCURSOR _arrowCursor;
HCURSOR _waitCursor;
public:
Cursors(Libs::Resources &res);
~Cursors();
HCURSOR loadCursor(intptr cursorId);
};
} // namespace Gfx
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,276 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/memstream.h"
#include "bagel/mfc/gfx/dialog_template.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
CDialogTemplate::CDialogTemplate(LPCDLGTEMPLATE pTemplate) {
setTemplate(pTemplate);
}
CDialogTemplate::CDialogTemplate(HGLOBAL hGlobal) {
LPDLGTEMPLATE dlgTemplate = (LPDLGTEMPLATE)GlobalLock(hGlobal);
setTemplate(dlgTemplate);
GlobalUnlock(hGlobal);
}
bool CDialogTemplate::setTemplate(LPCDLGTEMPLATE pTemplate) {
Common::MemoryReadStream src((const byte *)pTemplate, 99999);
_header.load(src);
_items.clear();
_items.resize(_header._itemCount);
for (auto &item : _items)
item.load(src);
return true;
}
bool CDialogTemplate::HasFont() const {
return false;
}
bool CDialogTemplate::SetFont(const char *lpFaceName, uint16 nFontSize) {
return false;
}
bool CDialogTemplate::SetSystemFont(uint16 nFontSize) {
return false;
}
bool CDialogTemplate::GetFont(CString &strFaceName, uint16 &nFontSize) const {
return false;
}
void CDialogTemplate::GetSizeInDialogUnits(SIZE *pSize) const {
}
void CDialogTemplate::GetSizeInPixels(SIZE *pSize) const {
}
bool CDialogTemplate::GetFont(LPCDLGTEMPLATE pTemplate,
CString &strFaceName, uint16 &nFontSize) {
return false;
}
/*--------------------------------------------*/
void CDialogTemplate::Header::load(Common::SeekableReadStream &src) {
byte bTerm;
_style = src.readUint32LE();
_itemCount = src.readByte();
_x = src.readSint16LE();
_y = src.readSint16LE();
_w = src.readSint16LE();
_h = src.readSint16LE();
bTerm = src.readByte();
switch (bTerm) {
case 0:
_menuName.clear();
break;
case 0xff:
// Int resource Id
src.skip(2);
break;
default:
src.seek(-1, SEEK_CUR);
_menuName = src.readString();
break;
}
_className = src.readString();
_caption = src.readString();
if (_style & DS_SETFONT) {
_fontInfo._pointSize = src.readUint16LE();
_fontInfo._fontName = src.readString();
} else {
_fontInfo._pointSize = 0;
_fontInfo._fontName.clear();
}
}
/*--------------------------------------------*/
void CDialogTemplate::Item::load(Common::SeekableReadStream &src) {
byte bTerm;
_x = src.readSint16LE();
_y = src.readSint16LE();
_w = src.readSint16LE();
_h = src.readSint16LE();
_id = src.readUint16LE();
_style = src.readUint32LE();
bTerm = src.readByte();
if (bTerm & 0x80) {
switch (bTerm) {
case 0x80: _className = "BUTTON"; break;
case 0x81: _className = "EDIT"; break;
case 0x82: _className = "STATIC"; break;
case 0x83: _className = "LISTBOX"; break;
case 0x84: _className = "SCROLLBAR"; break;
case 0x85: _className = "COMBOBOX"; break;
default:
_className.clear();
break;
}
} else {
src.seek(-1, SEEK_CUR);
_className = src.readString();
}
bTerm = src.readByte();
if (bTerm == 0xff) {
// Integer id, not documented
src.skip(2);
} else {
src.seek(-1, SEEK_CUR);
_title = src.readString();
}
_data.resize(src.readByte());
if (!_data.empty())
src.read(&_data[0], _data.size());
}
LOGFONT CDialogTemplate::ParseFontFromTemplate() {
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
Common::strcpy_s(lf.lfFaceName,
_header._fontInfo._fontName.c_str());
lf.lfHeight = _header._fontInfo._pointSize;
return lf;
}
void CDialogTemplate::getBaseUnits(int &x, int &y) {
// Step 1: Get the font
LOGFONT lf = ParseFontFromTemplate();
HFONT hFont = CreateFontIndirect(&lf);
// Step 2: Create a temporary DC and select the font
HDC hdc = CreateCompatibleDC(nullptr);
HGDIOBJ hOldFont = SelectObject(hdc, hFont);
// Step 3: Get metrics
TEXTMETRIC tm;
GetTextMetrics(hdc, &tm);
// Calculate DLU conversion
x = tm.tmAveCharWidth;
y = tm.tmHeight;
// Clean up
SelectObject(hdc, hOldFont);
DeleteDC(hdc);
DeleteObject(hFont);
}
void CDialogTemplate::loadTemplate(CDialog *dialog) {
int base_unit_x, base_unit_y;
getBaseUnits(base_unit_x, base_unit_y);
// Set up the overall window
RECT bounds = RectToRECT(
SafeMulDiv(_header._x, base_unit_x, 4),
SafeMulDiv(_header._y, base_unit_y, 8),
SafeMulDiv(_header._x + _header._w, base_unit_x, 4),
SafeMulDiv(_header._y + _header._h, base_unit_y, 8)
);
// WORKAROUND: For Hodj n Podj Boardgame dialog
bounds.right = MIN<long>(bounds.right, 640);
bounds.bottom = MIN<long>(bounds.bottom, 480);
CWnd *wndDialog = static_cast<CWnd *>(dialog);
wndDialog->Create(_header._className.c_str(),
_header._caption.c_str(),
_header._style | WS_POPUP | WS_VISIBLE,
bounds,
dialog->m_pParentWnd,
0
);
// Iterate through the controls
for (const auto &item : _items) {
CWnd *ctl;
if (item._className == "BUTTON")
ctl = new CButton();
else if (item._className == "EDIT")
ctl = new CEdit();
else if (item._className == "STATIC")
ctl = new CStatic();
else if (item._className == "LISTBOX")
ctl = new CListBox();
else if (item._className == "SCROLLBAR")
ctl = new CScrollBar();
else
error("Unhandle dialog item - %s",
item._className.c_str());
// Convert dialog DLU to actual pixels
int x1 = SafeMulDiv(item._x, base_unit_x, 4);
int y1 = SafeMulDiv(item._y, base_unit_y, 8);
int x2 = SafeMulDiv(item._x + item._w, base_unit_x, 4);
int y2 = SafeMulDiv(item._y + item._h, base_unit_y, 8);
// Set up control
bounds = RectToRECT(x1, y1, x2, y2);
ctl->Create(item._className.c_str(),
item._title.c_str(),
item._style | WS_VISIBLE | WS_TABSTOP,
bounds,
dialog,
item._id
);
// Register the control as needing to be
// freed when the dialog is closed
dialog->_ownedControls.push_back(ctl);
if (item._style & BS_DEFPUSHBUTTON)
dialog->_defaultId = item._id;
}
// Apply the font to the window and all child controls
LOGFONT lf = ParseFontFromTemplate();
dialog->_dialogFont.CreateFontIndirect(&lf);
dialog->SendMessageToDescendants(WM_SETFONT,
(WPARAM)dialog->_dialogFont.m_hObject, 0);
// Allow the dialog to set up replacement controls
CDataExchange exchange = { false };
dialog->DoDataExchange(&exchange);
}
} // namespace Gfx
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,138 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GFX_DIALOG_TEMPLATE_H
#define BAGEL_MFC_GFX_DIALOG_TEMPLATE_H
#include "common/array.h"
#include "common/stream.h"
#include "graphics/managed_surface.h"
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/afxstr.h"
namespace Bagel {
namespace MFC {
class CDialog;
namespace Gfx {
/*
* Dialog Styles
*/
#define DS_ABSALIGN 0x01L
#define DS_SYSMODAL 0x02L
#define DS_LOCALEDIT 0x20L /* 16-bit: Edit items get Local storage. 32-bit and up: meaningless. */
#define DS_SETFONT 0x40L /* User specified font for Dlg controls */
#define DS_MODALFRAME 0x80L /* Can be combined with WS_CAPTION */
#define DS_NOIDLEMSG 0x100L /* WM_ENTERIDLE message will not be sent */
#define DS_SETFOREGROUND 0x200L /* not in win3.1 */
// Template data pointers. Note that they're
// void *because in ScummVM we do endian-safe
// loading of the data being pointed to
typedef const void *LPCDLGTEMPLATE;
typedef void *LPDLGTEMPLATE;
class CDialogTemplate {
struct FontInfo {
byte _pointSize;
Common::String _fontName;
};
struct Header {
uint16 _style = 0;
byte _itemCount = 0;
int16 _x = 0, _y = 0;
int16 _w = 0, _h = 0;
Common::String _menuName;
Common::String _className;
Common::String _caption;
FontInfo _fontInfo;
void load(Common::SeekableReadStream &src);
};
struct Item {
uint16 _style = 0;
int16 _x = 0;
int16 _y = 0;
int16 _w = 0;
int16 _h = 0;
uint16 _id = 0;
Common::String _className;
uint16 _titleId = 0;
Common::String _title;
Common::Array<byte> _data;
void load(Common::SeekableReadStream &src);
};
private:
Header _header;
Common::Array<Item> _items;
private:
static byte *GetFontSizeField(LPCDLGTEMPLATE pTemplate);
static unsigned int GetTemplateSize(LPCDLGTEMPLATE *pTemplate);
bool setTemplate(LPCDLGTEMPLATE pTemplate);
/**
* Gets the base pixel x/y amounts, used for
* translating DLU units to pixel units
*/
void getBaseUnits(int &x, int &y);
LOGFONT ParseFontFromTemplate();
public:
HGLOBAL m_hTemplate = nullptr;
uint32 m_dwTemplateSize = 0;
bool m_bSystemFont = false;
public:
CDialogTemplate(LPCDLGTEMPLATE pTemplate = NULL);
CDialogTemplate(HGLOBAL hGlobal);
/**
* Sets up window with parsed template data
*/
void loadTemplate(CDialog *dialog);
bool HasFont() const;
bool SetFont(const char *lpFaceName, uint16 nFontSize);
bool SetSystemFont(uint16 nFontSize = 0);
bool GetFont(CString &strFaceName, uint16 &nFontSize) const;
void GetSizeInDialogUnits(SIZE *pSize) const;
void GetSizeInPixels(SIZE *pSize) const;
static bool GetFont(LPCDLGTEMPLATE pTemplate,
CString &strFaceName, uint16 &nFontSize);
};
} // namespace Gfx
using Gfx::LPDLGTEMPLATE;
using Gfx::LPCDLGTEMPLATE;
using Gfx::CDialogTemplate;
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,233 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "graphics/fonts/winfont.h"
#include "bagel/mfc/gfx/fonts.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
struct FontSizeOverride {
const char *_faceName;
int _height;
int _avgWidth;
int _charHeight;
};
static const FontSizeOverride FONT_SIZE_OVERRIDES[] = {
{ "MS Sans Serif", 8, 7, 13 },
{ "MS Sans Serif", 12, 10, 20 },
{ nullptr, 0, 0, 0 }
};
Fonts::~Fonts() {
_fonts.clear();
}
int Fonts::addFontResource(const char *filename) {
if (!resExists(filename)) {
_fontResources.push_back(filename);
return 1;
}
return 0;
}
bool Fonts::removeFontResource(const char *filename) {
int idx = resIndexOf(filename);
if (idx != -1) {
_fontResources.remove_at(idx);
return true;
} else {
return false;
}
}
HFONT Fonts::createFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, byte bItalic, byte bUnderline,
byte cStrikeOut, byte nCharSet, byte nOutPrecision,
byte nClipPrecision, byte nQuality, byte nPitchAndFamily,
const char *lpszFacename) {
Gfx::Font *font = nullptr;
// for nHeight, -ve means char height (which ScummVM uses),
// whilst +ve means cell height
int charHeight;
if (nHeight < 0) {
charHeight = ABS(nHeight);
} else {
// Cell to char height mappings
// TODO: This needs to be set properly
static const int8 HEIGHTS[][2] = {
{ 8, 8 }, // Default font
{ 10, 10 }, // Boardgame dialog
{ 12, 8 },
{ 14, 9 }, { 16, 10 }, { 18, 24 },
{ 21, 12 }, // The Gesng Gme
{ 0, 0 }
};
charHeight = nHeight * 16 / 24; // Rough default
for (int i = 0; HEIGHTS[i][0]; ++i) {
if (nHeight == HEIGHTS[i][0]) {
charHeight = HEIGHTS[i][1];
break;
}
}
}
// First scan for an existing cached copy of the font
for (auto &it : _fonts) {
if (it._faceName == lpszFacename &&
it._height == nHeight) {
font = it._font;
break;
}
}
if (!font) {
// Create the font
Graphics::WinFont *winFont = new Graphics::WinFont();
for (auto &filename : _fontResources) {
// Note: Windows does some rounding up or down to
// the closest size for a given face name if the
// requested size isn't available
for (int h = charHeight; h >= 2; --h) {
if (winFont->loadFromFON(filename, Graphics::WinFontDirEntry(
lpszFacename, (h >= 6) ? h : charHeight + (6 - h)))) {
// Loaded successfully
font = new Gfx::Font(winFont, lpszFacename, nHeight);
// Add to the font cache
_fonts.push_back(FontEntry());
_fonts.back().set(lpszFacename, nHeight, font);
break;
}
}
if (font)
break;
}
if (!font)
delete winFont;
}
// If we found a found, return a font Impl,
// which can be cast as a HFONT for our MFC classes
if (font) {
CFont::Impl *f = new CFont::Impl(font);
return f;
}
error("Could not locate font %s - size %d",
lpszFacename, nHeight);
return nullptr;
}
int Fonts::resIndexOf(const char *filename) const {
for (uint i = 0; i < _fontResources.size(); ++i) {
if (!strcmp(_fontResources[i], filename))
return i;
}
return -1;
}
HFONT Fonts::getFont(const char *lpszFacename, int nHeight) {
return createFont(nHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, OUT_RASTER_PRECIS, 0, PROOF_QUALITY, FF_ROMAN, lpszFacename);
}
/*--------------------------------------------*/
Fonts::FontEntry::~FontEntry() {
delete _font;
}
/*--------------------------------------------*/
Font::Font(Graphics::Font *font, const Common::String &faceName, int height,
DisposeAfterUse::Flag disposeAfterUse) :
_font(font), _faceName(faceName), _height(height),
_charWidth(0), _charHeight(0),
_disposeAfterUse(disposeAfterUse) {
for (const FontSizeOverride *aw = FONT_SIZE_OVERRIDES; aw->_faceName; ++aw) {
if (faceName == aw->_faceName && height == aw->_height) {
_charWidth = aw->_avgWidth;
_charHeight = aw->_charHeight;
return;
}
}
}
Font::~Font() {
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _font;
}
int Font::getFontHeight() const {
return _font->getFontHeight();
}
int Font::getFontAscent() const {
return _font->getFontAscent();
}
int Font::getFontDescent() const {
return _font->getFontDescent();
}
int Font::getFontLeading() const {
return _font->getFontLeading();
}
int Font::getMaxCharWidth() const {
return _font->getMaxCharWidth() + 1;
}
int Font::getCharWidth(uint32 chr) const {
return _font->getCharWidth(chr) + 1;
}
int Font::getKerningOffset(uint32 left, uint32 right) const {
return _font->getKerningOffset(left, right);
}
void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
_font->drawChar(dst, chr, x, y, color);
_font->drawChar(dst, chr, x + 1, y, color);
}
void Font::drawChar(Graphics::ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const {
const int charW = _font->getCharWidth(chr) + 1;
const int charH = _font->getFontHeight();
if (x >= 0 && y >= 0 && (x + charW) <= dst->w &&
(y + charH) <= dst->h) {
_font->drawChar(dst, chr, x, y, color);
_font->drawChar(dst, chr, x + 1, y, color);
}
}
} // namespace Gfx
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,132 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GFX_FONTS_H
#define BAGEL_MFC_GFX_FONTS_H
#include "common/array.h"
#include "common/types.h"
#include "graphics/font.h"
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/libs/resources.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
/**
* Font derived class that makes the
* original face name and height visible.
* It also bolds the font, which seems to
* more closely match plain text in the
* original Hodj n Podj.
*
* Note: We cache the underlying Graphics::Font
* for the lifetime of the application, but
* Font instances are temporary, and are what
* we cast as HFONT. And as such, will be destroyed.
*/
class Font : public Graphics::Font {
private:
Graphics::Font *_font;
DisposeAfterUse::Flag _disposeAfterUse =
DisposeAfterUse::YES;
Common::String _faceName;
int _height;
int _charWidth;
int _charHeight;
public:
Font(Graphics::Font *font, const Common::String &faceName, int height,
DisposeAfterUse::Flag disposeAfterUse =
DisposeAfterUse::YES);
~Font() override;
int getFontHeight() const override;
int getFontAscent() const override;
int getFontDescent() const override;
int getFontLeading() const override;
int getMaxCharWidth() const override;
int getCharWidth(uint32 chr) const override;
int getKerningOffset(uint32 left, uint32 right) const override;
void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
void drawChar(Graphics::ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const override;
const Common::String &getFaceName() const {
return _faceName;
}
int getHeight() const {
return _height;
}
int getCharWidth() const {
return _charWidth;
}
int getCharHeight() const {
return _charHeight;
}
};
/**
* Main fonts cache
*/
class Fonts {
struct FontEntry {
Common::String _faceName;
int _height = 0;
Font *_font = nullptr;
void set(const Common::String &faceName,
int height, Font *font) {
_faceName = faceName;
_height = height;
_font = font;
}
~FontEntry();
};
private:
//Libs::Resources &_res;
Common::Array<const char *> _fontResources;
Common::List<FontEntry> _fonts;
int resIndexOf(const char *filename) const;
bool resExists(const char *filename) const {
return resIndexOf(filename) != -1;
}
public:
Fonts(Libs::Resources &res) /*: _res(res) */ {}
~Fonts();
int addFontResource(const char *filename);
bool removeFontResource(const char *filename);
HFONT createFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, byte bItalic, byte bUnderline,
byte cStrikeOut, byte nCharSet, byte nOutPrecision,
byte nClipPrecision, byte nQuality, byte nPitchAndFamily,
const char *lpszFacename);
HFONT getFont(const char *lpszFacename, int nHeight);
};
} // namespace Gfx
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/mfc/gfx/palette_map.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
PaletteMap::PaletteMap(const Graphics::Palette &src,
const Graphics::Palette &dest) : _srcPalCount(src.size()) {
assert(src.size() == 256 && dest.size() == 256);
// Set up lookup map
Graphics::PaletteLookup lookup(dest.data(), dest.size());
_map = lookup.createMap(src.data(), src.size());
// Hack: Index 255 must always remain mapped to 255,
// in order for transparency to work. In cases where the
// palette has multiple White entries, PaletteLookup could
// end up using the first match, not the last (255) one
if (!_map) {
_map = new uint32[256];
for (int i = 0; i < 256; ++i)
_map[i] = i;
}
byte r, g, b;
for (int i = 0; i < 256; ++i) {
src.get(i, r, g, b);
if (r == 0xff && g == 0xff && b == 0xff)
_map[i] = 0xff;
}
}
PaletteMap::~PaletteMap() {
delete[] _map;
}
void PaletteMap::map(const byte *src, byte *dest, size_t len) {
if (_map) {
for (; len > 0; --len, ++src, ++dest)
*dest = _map[*src];
} else {
// Identical palettes, so pixels can just be copied
Common::copy(src, src + len, dest);
}
}
} // namespace Gfx
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,51 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GFX_PALETTE_MAP_H
#define BAGEL_MFC_GFX_PALETTE_MAP_H
#include "graphics/palette.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
/**
* Simple wrapper over Graphics::PaletteLookup
*/
class PaletteMap {
private:
uint32 *_map;
size_t _srcPalCount;
public:
PaletteMap(const Graphics::Palette &src,
const Graphics::Palette &dest);
~PaletteMap();
void map(const byte *src, byte *dest, size_t len);
};
} // namespace Gfx
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,249 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/mfc/gfx/surface.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
Surface::XIterator::XIterator(YIterator *rowIter) :
_rowIter(rowIter), _surface(rowIter->_surface) {
const CPoint org = _surface->getViewportOrg();
_xMin = _surface->_clipRect.left - org.x;
_xMax = _surface->_clipRect.right - org.x;
}
Surface::XIterator &Surface::XIterator::operator=(int x) {
//const CPoint org = _surface->getViewportOrg();
_x = x;
int y = _rowIter->_y;
if (x < _xMin || x >= _xMax ||
y < _rowIter->_yMin || y >= _rowIter->_yMax)
_pixelP = &_dummyPixel;
else
_pixelP = _surface->getBasePtr(_x, _rowIter->_y);
return *this;
}
Surface::XIterator &Surface::XIterator::operator++() {
++_x;
int y = _rowIter->_y;
if (y < _rowIter->_yMin || y >= _rowIter->_yMax)
_pixelP = &_dummyPixel;
else if (_x == _xMin)
_pixelP = _surface->getBasePtr(_x, y);
else if (_x >= _xMax)
_pixelP = &_dummyPixel;
else if (_x >= _xMin)
++_pixelP;
return *this;
}
bool Surface::XIterator::operator<(int xEnd) const {
return _x < xEnd;
}
Surface::XIterator::operator byte *() {
// Keep resetting the dummy pixel, in case
// the pixel pointer is pointing to it
_dummyPixel = 0;
// Return the pixel pointer
return _pixelP;
}
/*--------------------------------------------*/
Surface::YIterator::YIterator(Surface *surface) : _surface(surface) {
assert(surface && surface->format.bytesPerPixel <= 1);
CPoint org = surface->getViewportOrg();
_yMin = surface->_clipRect.top - org.y;
_yMax = surface->_clipRect.bottom - org.y;
}
Surface::YIterator &Surface::YIterator::operator=(int y) {
_y = y;
return *this;
}
Surface::YIterator &Surface::YIterator::operator++() {
++_y;
return *this;
}
bool Surface::YIterator::operator<(int yEnd) const {
return _y < yEnd;
}
/*--------------------------------------------*/
void Surface::create(int16 width, int16 height) {
_surface.create(width, height);
_viewportOrg = CPoint(0, 0);
resetClip();
}
void Surface::create(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat) {
_surface.create(width, height, pixelFormat);
_viewportOrg = CPoint(0, 0);
resetClip();
}
void Surface::create(Graphics::ManagedSurface &surf, const Common::Rect &bounds) {
_surface.create(surf, bounds);
_viewportOrg = CPoint(0, 0);
resetClip();
}
void Surface::setClipRect(const Common::Rect &r) {
_clipRect = r;
}
Common::Rect Surface::getClipRect() const {
return _clipRect;
}
void Surface::resetClip() {
setClipRect(Common::Rect(0, 0, _surface.w, _surface.h));
}
int Surface::intersectClipRect(const Common::Rect &r) {
setClipRect(_clipRect.findIntersectingRect(r));
return _clipRect.isEmpty() ? NULLREGION : SIMPLEREGION;
}
int Surface::offsetClipRect(int x, int y) {
if (_clipRect.isEmpty()) {
return NULLREGION;
} else {
Common::Rect r = _clipRect;
r.translate(x, y);
setClipRect(r);
return SIMPLEREGION;
}
}
CPoint Surface::getViewportOrg() const {
return _viewportOrg;
}
void Surface::setViewportOrg(const CPoint &pt) {
_viewportOrg = pt;
}
void Surface::offsetViewportOrg(int x, int y) {
_viewportOrg.x += x;
_viewportOrg.y += y;
}
byte *Surface::getBasePtr(int x, int y) {
assert(format.bytesPerPixel == 1);
x += _viewportOrg.x;
y += _viewportOrg.y;
assert(x >= 0 && y >= 0 && x < this->w && y < this->h);
return (byte *)_surface.getBasePtr(x, y);
}
void Surface::addDirtyRect(const Common::Rect &r) {
Common::Rect tmp = r;
tmp.translate(_viewportOrg.x, _viewportOrg.y);
tmp = tmp.findIntersectingRect(_clipRect);
_surface.addDirtyRect(tmp);
}
void Surface::fillRect(const Common::Rect &r, uint color) {
Common::Rect tmp = r;
tmp.translate(_viewportOrg.x, _viewportOrg.y);
tmp = tmp.findIntersectingRect(_clipRect);
if (!tmp.isEmpty())
_surface.fillRect(tmp, color);
}
void Surface::frameRect(const Common::Rect &r, uint color) {
Common::Rect tmp = r;
tmp.translate(_viewportOrg.x, _viewportOrg.y);
tmp = tmp.findIntersectingRect(_clipRect);
if (!tmp.isEmpty())
_surface.frameRect(r, color);
}
void Surface::drawEllipse(int x0, int y0, int x1, int y1, uint32 color, bool filled) {
x0 += _viewportOrg.x;
x1 += _viewportOrg.x;
y0 += _viewportOrg.y;
y1 += _viewportOrg.y;
assert(x0 >= 0 && y0 >= 0 && x1 <= _surface.w && y1 <= _surface.h);
_surface.drawEllipse(x0, y0, x1, y1, color, filled);
}
void Surface::drawLine(int x0, int y0, int x1, int y1, uint32 color) {
x0 += _viewportOrg.x;
x1 += _viewportOrg.x;
y0 += _viewportOrg.y;
y1 += _viewportOrg.y;
assert(x0 >= 0 && y0 >= 0 && x1 <= _surface.w && y1 <= _surface.h);
_surface.drawLine(x0, y0, x1, y1, color);
}
void Surface::hLine(int x0, int y, int x1, uint32 color) {
x0 += _viewportOrg.x;
x1 += _viewportOrg.x;
y += _viewportOrg.y;
assert(x0 >= 0 && y >= 0 && x1 <= _surface.w && y <= _surface.h);
_surface.hLine(x0, y, x1, color);
}
uint32 Surface::getPixel(int x, int y) {
x += _viewportOrg.x;
y += _viewportOrg.y;
assert(x >= 0 && y >= 0 && x <= _surface.w && y <= _surface.h);
assert(format.bytesPerPixel == 1);
return *(byte *)getBasePtr(x, y);
}
Graphics::ManagedSurface Surface::getSubArea(const Common::Rect &r) {
Common::Rect tmp = r;
tmp.translate(_viewportOrg.x, _viewportOrg.y);
assert(tmp.left >= 0 && tmp.top >= 0 &&
tmp.right <= _surface.w && tmp.bottom <= _surface.h);
return Graphics::ManagedSurface(_surface, tmp);
}
} // namespace Gfx
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,130 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GFX_SURFACE_H
#define BAGEL_MFC_GFX_SURFACE_H
#include "graphics/managed_surface.h"
#include "bagel/mfc/atltypes.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
class Surface;
/**
* Surface class
*/
class Surface {
public:
class YIterator;
/**
* Column iterator
*/
class XIterator {
private:
Surface *_surface;
YIterator *_rowIter;
int _x = 0;
int _xMin, _xMax;
byte *_pixelP = nullptr;
byte _dummyPixel = 0;
public:
XIterator(YIterator *rowIter);
XIterator &operator=(int x);
XIterator &operator++();
bool operator<(int xEnd) const;
operator byte *();
};
/**
* Row iterator
*/
class YIterator {
friend class XIterator;
private:
Surface *_surface;
int _y = 0;
int _yMin, _yMax;
public:
YIterator(Surface *surface);
YIterator &operator=(int y);
YIterator &operator++();
bool operator<(int yMax) const;
};
private:
Graphics::ManagedSurface _surface;
Common::Rect _clipRect;
CPoint _viewportOrg;
public:
Graphics::PixelFormat &format = _surface.format;
int16 &w = _surface.w;
int16 &h = _surface.h;
int32 &pitch = _surface.pitch;
public:
void create(int16 width, int16 height);
void create(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat);
void create(Graphics::ManagedSurface &surf, const Common::Rect &bounds);
void setClipRect(const Common::Rect &r);
Common::Rect getClipRect() const;
void resetClip();
int intersectClipRect(const Common::Rect &r);
int offsetClipRect(int x, int y);
CPoint getViewportOrg() const;
void setViewportOrg(const CPoint &pt);
void offsetViewportOrg(int x, int y);
byte *getBasePtr(int x, int y);
void *getPixels() {
return _surface.getPixels();
}
const void *getPixels() const {
return _surface.getPixels();
}
void addDirtyRect(const Common::Rect &r);
void setPalette(const byte *colors, int start, int num) {
_surface.setPalette(colors, start, num);
}
void fillRect(const Common::Rect &r, uint color);
void frameRect(const Common::Rect &r, uint color);
void drawEllipse(int x0, int y0, int x1, int y1, uint32 color, bool filled);
void drawLine(int x0, int y0, int x1, int y1, uint32 color);
void hLine(int x0, int y, int x1, uint32 color);
uint32 getPixel(int x, int y);
Graphics::ManagedSurface getSubArea(const Common::Rect &r);
};
} // namespace Gfx
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,161 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/mfc/gfx/text_render.h"
#include "bagel/mfc/wingdi.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
CSize TextRender::renderText(const Common::String &str,
Gfx::Surface *dest, Graphics::Font *font,
uint textCol, LPCRECT lpRect, unsigned int nFormat,
const Common::Array<int> &tabStops,
int nTabOrigin, uint bkColor, int bkMode,
uint textColor, uint textAlign) {
const int maxWidth = lpRect->right - lpRect->left;
Common::Rect textRect = *lpRect;
Common::StringArray lines;
CSize size;
// FIXME: Currently doing a hack to replace
// all tabs with spaces, rather than honoring
// the tab stops array
Common::String text = str;
uint p;
while ((p = text.findFirstOf('\t')) != Common::String::npos) {
text.deleteChar(p);
text.insertString(" ", p);
}
if (nFormat & DT_SINGLELINE) {
lines.push_back(text);
} else {
// Hotkeys aren't supported on multi-line text
assert((nFormat & DT_NOPREFIX) || !str.contains('&'));
// Perform word wrapping of the text as necessary
wordWrapText(font, text, tabStops, maxWidth, lines);
}
// Handle vertical alignment
const int linesHeight = lines.size() * font->getFontHeight();
if (nFormat & DT_BOTTOM) {
textRect.moveTo(textRect.left,
MAX<int16>(lpRect->top, textRect.bottom - linesHeight));
}
if (nFormat & DT_VCENTER) {
textRect.moveTo(textRect.left, MAX<int16>(lpRect->top,
lpRect->top + ((lpRect->bottom - lpRect->top) -
linesHeight) / 2));
}
// Iterate through the lines
for (const Common::String &line : lines) {
// Constrain within passed rect
if (textRect.top >= lpRect->bottom)
break;
const int lineWidth = getStringWidth(font, line);
size.cx = MAX(size.cx, lineWidth);
// Form sub-rect for the single line
Common::Rect lineRect(textRect.left, textRect.top,
textRect.right, textRect.top + font->getFontHeight());
// Handle horizontal alignment
if (nFormat & DT_RIGHT) {
lineRect.moveTo(MAX<int16>(lineRect.left,
lineRect.right - lineWidth),
lineRect.top);
}
if (nFormat & DT_CENTER) {
lineRect.moveTo(MAX<int16>(lineRect.left,
lineRect.left + (lineRect.width() - lineWidth) / 2),
lineRect.top);
}
lineRect.left = MAX<int16>(lineRect.left, 0);
lineRect.right = MIN<int16>(lineRect.right, dest->w);
// If the background is opaque, clear it
if (bkMode == OPAQUE)
dest->fillRect(lineRect, bkColor);
// Write the actual text. This is slightly
// complicated to detect '&' characters when
// DT_NOPREFIX isn't set
Common::String fragment;
Common::String tempLine = line;
while (!tempLine.empty()) {
if (!(nFormat & DT_NOPREFIX) && tempLine.firstChar() == '&') {
tempLine.deleteChar(0);
// Draw an underline
const int x1 = lineRect.left;
const int x2 = x1 + font->getCharWidth(tempLine.firstChar()) - 1;
const int y = lineRect.top + font->getFontAscent() + 1;
dest->hLine(x1, y, x2, textCol);
}
uint idx = (nFormat & DT_NOPREFIX) ? Common::String::npos :
tempLine.findFirstOf('&');
if (idx == Common::String::npos) {
fragment = tempLine;
tempLine.clear();
} else {
fragment = Common::String(tempLine.c_str(), tempLine.c_str() + idx);
tempLine = Common::String(tempLine.c_str() + fragment.size());
}
Graphics::ManagedSurface area = dest->getSubArea(lineRect);
font->drawString(&area, fragment, 0, 0, area.w, textCol);
lineRect.left += getStringWidth(font, fragment);
}
// Move to next line
textRect.top += font->getFontHeight();
}
return size;
}
int TextRender::getStringWidth(Graphics::Font *font, const Common::String &str) {
Common::String tempLine = str;
uint idx;
while ((idx = tempLine.findFirstOf('&')) != Common::String::npos)
tempLine.deleteChar(idx);
return font->getStringWidth(tempLine);
}
void TextRender::wordWrapText(Graphics::Font *font, const Common::String &str,
const Common::Array<int> tabStops, int maxWidth,
Common::StringArray &lines) {
font->wordWrapText(str, maxWidth, lines);
}
} // namespace Gfx
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,55 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GFX_TEXT_RENDER_H
#define BAGEL_MFC_GFX_TEXT_RENDER_H
#include "common/str-array.h"
#include "graphics/font.h"
#include "bagel/mfc/gfx/surface.h"
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/atltypes.h"
#include "bagel/mfc/wingdi.h"
namespace Bagel {
namespace MFC {
namespace Gfx {
class TextRender {
protected:
CSize renderText(const Common::String &str,
Gfx::Surface *dest, Graphics::Font *font,
uint textCol, LPCRECT lpRect, unsigned int nFormat,
const Common::Array<int> &tabStops,
int nTabOrigin, uint bkColor, int bkMode,
uint textColor, uint textAlign);
void wordWrapText(Graphics::Font *font, const Common::String &str,
const Common::Array<int> tabStops,
int maxWidth, Common::StringArray &lines);
int getStringWidth(Graphics::Font *font, const Common::String &str);
};
} // namespace Gfx
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,284 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/file.h"
#include "common/system.h"
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/global_functions.h"
namespace Bagel {
namespace MFC {
struct MemBlock {
byte *_ptr;
size_t _size;
MemBlock(size_t size, bool clearFlag) : _size(size) {
_ptr = (byte *)malloc(size);
if (clearFlag)
Common::fill(_ptr, _ptr + size, 0);
}
~MemBlock() {
free(_ptr);
}
};
HGLOBAL GlobalAlloc(unsigned int uFlags, size_t dwBytes) {
return new MemBlock(dwBytes,
uFlags == GMEM_ZEROINIT);
}
void *GlobalLock(HGLOBAL hMem) {
return ((MemBlock *)hMem)->_ptr;
}
bool GlobalUnlock(HGLOBAL hMem) {
return true;
}
HGLOBAL GlobalFree(HGLOBAL hMem) {
delete (MemBlock *)hMem;
return nullptr;
}
size_t GlobalSize(HGLOBAL hMem) {
return ((MemBlock *)hMem)->_size;
}
size_t GlobalCompact(uint32 dwMinFree) {
// No implementation
return 999999;
}
int MessageBox(HWND hWnd, const char *lpText,
const char *lpCaption, unsigned int uType) {
error("%s %s", lpText, lpCaption);
return 0;
}
int MessageBox(const char *lpText, const char *lpCaption, unsigned int uType) {
error("%s %s", lpText, lpCaption);
return 0;
}
int MessageBox(const char *lpText) {
error("%s", lpText);
return 0;
}
unsigned int GetPrivateProfileInt(const char *lpAppName,
const char *lpKeyName, int nDefault, const char *lpFileName) {
return AfxGetApp()->GetProfileInt(lpAppName, lpKeyName, nDefault);
}
extern uint32 GetPrivateProfileString(const char *lpAppName,
const char *lpKeyName, const char *lpDefault, char *lpReturnedString,
uint32 nSize, const char *lpFileName) {
CString str = AfxGetApp()->GetProfileString(lpAppName,
lpKeyName, lpDefault);
Common::strcpy_s(lpReturnedString, nSize, str.c_str());
return true;
}
bool WritePrivateProfileString(
const char *lpAppName, const char *lpKeyName,
const char *lpString, const char *lpFileName) {
AfxGetApp()->WriteProfileString(lpAppName,
lpKeyName, lpString);
return true;
}
HTASK GetCurrentTask() {
return 0;
}
FARPROC MakeProcInstance(FARPROC lpProc, HINSTANCE hInstance) {
// Just return the passed proc as is
return lpProc;
}
void FreeProcInstance(FARPROC lpProc) {
// No implementation needed
}
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn,
HINSTANCE hmod, HTASK dwThreadId) {
// We only currently support keyboard in ScummVM
assert(idHook == WH_KEYBOARD);
return AfxGetApp()->HookKeyboard(lpfn);
}
bool UnhookWindowsHookEx(HHOOK hhk) {
AfxGetApp()->UnhookKeyboard(hhk);
return true;
}
LRESULT CallNextHookEx(HHOOK hhk, int nCode,
WPARAM wParam, LPARAM lParam) {
error("TODO: CallNextHookEx");
}
uintptr SetTimer(HWND hWnd, uintptr nIDEvent, unsigned int nElapse,
void (CALLBACK * lpfnTimer)(HWND, unsigned int, uintptr, uint32)) {
return AfxGetApp()->SetTimer(hWnd, nIDEvent, nElapse, lpfnTimer);
}
bool KillTimer(HWND hWnd, uintptr nIDEvent) {
return AfxGetApp()->KillTimer(hWnd, nIDEvent);
}
void Sleep(unsigned int milli) {
g_system->delayMillis(milli);
}
uint32 GetTickCount() {
return g_system->getMillis();
}
Common::SeekableReadStream *OpenFile(const char *filename) {
Common::String fname(filename);
if (fname.hasPrefix(".\\"))
fname = Common::String(fname.c_str() + 2);
// In cases where ..\ is used as a prefix, presume
// that we're only a single level deep, and the remainder
// is relative to the game's root folder. So we can
// just strip it off, and Common::File will find it
if (fname.hasPrefix("..\\"))
fname = Common::String(fname.c_str() + 3);
fname.replace('\\', '/');
Common::File *f = new Common::File();
if (f->open(Common::Path(fname)))
return f;
delete f;
return nullptr;
}
bool FileExists(const char *filename) {
Common::SeekableReadStream *rs = OpenFile(filename);
bool result = rs != nullptr;
delete rs;
return result;
}
long FileLength(const char *filename) {
Common::SeekableReadStream *rs = OpenFile(filename);
long result = rs ? rs->size() : -1;
delete rs;
return result;
}
bool PeekMessage(LPMSG lpMsg, HWND hWnd,
unsigned int wMsgFilterMin, unsigned int wMsgFilterMax,
unsigned int wRemoveMsg) {
return AfxGetApp()->PeekMessage(lpMsg, hWnd,
wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
}
void TranslateMessage(LPMSG lpMsg) {
AfxGetApp()->TranslateMessage(lpMsg);
}
void DispatchMessage(LPMSG lpMsg) {
AfxGetApp()->DispatchMessage(lpMsg);
}
bool PostMessage(HWND hWnd, unsigned int Msg,
WPARAM wParam, LPARAM lParam) {
return AfxGetApp()->PostMessage(hWnd, Msg, wParam, lParam);
}
LRESULT SendMessage(HWND hWnd, unsigned int Msg,
WPARAM wParam, LPARAM lParam) {
CWnd *wnd = CWnd::FromHandle(hWnd);
return wnd->SendMessage(Msg, wParam, lParam);
}
HINSTANCE AfxGetResourceHandle() {
// Can be left as a default value for ScummVM
return nullptr;
}
HINSTANCE AfxFindResourceHandle(const char *lpszName, const char *lpszType) {
return AfxGetResourceHandle();
}
HRSRC FindResource(HMODULE hModule,
const char *lpName, const char *lpType) {
return AfxGetApp()->findResource(lpName, lpType);
}
size_t SizeofResource(HMODULE hModule, HRSRC hResInfo) {
return AfxGetApp()->sizeofResource(hResInfo);
}
HGLOBAL LoadResource(HMODULE hModule, HRSRC hResInfo) {
return AfxGetApp()->loadResource(hResInfo);
}
void *LockResource(HGLOBAL hResData) {
return AfxGetApp()->lockResource(hResData);
}
void UnlockResource(HGLOBAL hResData) {
return AfxGetApp()->unlockResource(hResData);
}
bool FreeResource(HGLOBAL hResData) {
return AfxGetApp()->freeResource(hResData);
}
HFONT CreateFontIndirect(const LOGFONT *lf) {
return AfxGetApp()->getFont(
lf->lfFaceName, lf->lfHeight);
}
bool AfxExtractSubString(CString &rString, const char *lpszFullString,
int iSubString, char chSep) {
if (lpszFullString == nullptr)
return false;
while (iSubString--) {
lpszFullString = strchr(lpszFullString, chSep);
if (!lpszFullString) {
rString.Empty();
return false;
}
lpszFullString++; // Point past the separator
}
const char *lpchEnd = strchr(lpszFullString, chSep);
int nLen = !lpchEnd ? strlen(lpszFullString) :
(int)(lpchEnd - lpszFullString);
ASSERT(nLen >= 0);
rString = CString(lpszFullString, nLen);
return true;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,163 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_GLOBAL_FUNCTIONS_H
#define BAGEL_MFC_GLOBAL_FUNCTIONS_H
#include "common/stream.h"
#include "bagel/mfc/afxstr.h"
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/winnt.h"
namespace Bagel {
namespace MFC {
class CWinApp;
class CWnd;
/* Global Memory Flags */
#define GMEM_FIXED 0x0000
#define GMEM_MOVEABLE 0x0002
#define GMEM_NOCOMPACT 0x0010
#define GMEM_NODISCARD 0x0020
#define GMEM_ZEROINIT 0x0040
#define GMEM_MODIFY 0x0080
#define GMEM_DISCARDABLE 0x0100
#define GMEM_NOT_BANKED 0x1000
#define GMEM_SHARE 0x2000
#define GMEM_DDESHARE 0x2000
#define GMEM_NOTIFY 0x4000
#define GMEM_LOWER GMEM_NOT_BANKED
#define GMEM_VALID_FLAGS 0x7F72
#define GMEM_INVALID_HANDLE 0x8000
#define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT)
#define GPTR (GMEM_FIXED | GMEM_ZEROINIT)
#define MB_ICONHAND 0x00000010L
#define MB_ICONQUESTION 0x00000020L
#define MB_ICONEXCLAMATION 0x00000030L
#define MB_ICONASTERISK 0x00000040L
#define MB_ICONINFORMATION MB_ICONASTERISK
#define MB_ICONSTOP MB_ICONHAND
extern CWinApp *AfxGetApp();
extern CWnd *AfxGetMainWnd();
extern HINSTANCE AfxGetInstanceHandle();
extern int LoadString(HINSTANCE hInstance,
unsigned int uID, char *lpBuffer, int cchBufferMax);
extern HMODULE LoadLibrary(const char *lpLibFileName);
extern void FreeLibrary(HMODULE hModule);
extern FARPROC GetProcAddress(HMODULE hModule,
const char * lpProcName);
extern HMODULE GetModuleHandle(const char *lpModuleName);
extern const char *AFXAPI AfxRegisterWndClass(unsigned int nClassStyle,
HCURSOR hCursor = 0, HBRUSH hbrBackground = 0, HICON hIcon = 0);
extern bool GetClassInfo(HINSTANCE hInstance,
const char *lpClassName, LPWNDCLASS lpWndClass);
extern int GetSystemMetrics(int nIndex);
extern HGLOBAL GlobalAlloc(unsigned int uFlags, size_t dwBytes);
extern void *GlobalLock(HGLOBAL hMem);
extern bool GlobalUnlock(HGLOBAL hMem);
extern HGLOBAL GlobalFree(HGLOBAL hMem);
extern size_t GlobalSize(HGLOBAL hMem);
extern size_t GlobalCompact(uint32 dwMinFree);
#define LocalAlloc GlobalAlloc
#define LocalLock GlobalLock
#define LocalUnlock GlobalUnlock
#define LocalFree GlobalFree
#define LocalCompact GlobalCompact
#define GetFreeSpace(w) (0x100000L)
extern int MessageBox(HWND hWnd, const char *lpText,
const char *lpCaption, unsigned int uType);
extern int MessageBox(const char *lpText, const char *lpCaption, unsigned int uType = 0);
extern int MessageBox(const char *lpText);
extern unsigned int GetPrivateProfileInt(const char *lpAppName,
const char *lpKeyName, int nDefault, const char *lpFileName);
extern uint32 GetPrivateProfileString(const char *lpAppName,
const char *lpKeyName, const char *lpDefault, char * lpReturnedString,
uint32 nSize, const char *lpFileName);
extern bool WritePrivateProfileString(
const char *lpAppName, const char *lpKeyName,
const char *lpString, const char *lpFileName);
extern HTASK GetCurrentTask();
extern FARPROC MakeProcInstance(FARPROC lpProc, HINSTANCE hInstance);
extern void FreeProcInstance(FARPROC lpProc);
extern HHOOK SetWindowsHookEx(int idHook,
HOOKPROC lpfn, HINSTANCE hmod, HTASK dwThreadId);
extern bool UnhookWindowsHookEx(HHOOK hhk);
extern LRESULT CallNextHookEx(HHOOK hhk, int nCode,
WPARAM wParam, LPARAM lParam);
extern uintptr SetTimer(HWND hWnd, uintptr nIDEvent, unsigned int nElapse,
void (CALLBACK *lpfnTimer)(HWND, unsigned int, uintptr, uint32) = nullptr);
extern bool KillTimer(HWND hWnd, uintptr nIDEvent);
extern void Sleep(unsigned int milli);
extern uint32 GetTickCount();
extern Common::SeekableReadStream *OpenFile(const char *filename);
extern bool FileExists(const char *filename);
extern long FileLength(const char *filename);
extern bool PeekMessage(LPMSG lpMsg, HWND hWnd,
unsigned int wMsgFilterMin, unsigned int wMsgFilterMax,
unsigned int wRemoveMsg);
extern void TranslateMessage(LPMSG lpMsg);
extern void DispatchMessage(LPMSG lpMsg);
extern bool PostMessage(HWND hWnd, unsigned int Msg,
WPARAM wParam, LPARAM lParam);
extern LRESULT SendMessage(HWND hWnd, unsigned int Msg,
WPARAM wParam, LPARAM lParam);
extern HINSTANCE AfxGetResourceHandle();
extern HINSTANCE AfxFindResourceHandle(const char *lpszName, const char *lpszType);
extern HRSRC FindResource(HMODULE hModule,
const char *lpName, const char *lpType);
extern size_t SizeofResource(HMODULE hModule, HRSRC hResInfo);
extern HGLOBAL LoadResource(HMODULE hModule, HRSRC hResInfo);
extern void *LockResource(HGLOBAL hResData);
extern void UnlockResource(HGLOBAL hResData);
extern bool FreeResource(HGLOBAL hResData);
extern HFONT CreateFontIndirect(const LOGFONT *lf);
extern bool AfxExtractSubString(CString &rString, const char *lpszFullString,
int iSubString, char chSep = '\n');
inline char *strUpper(char *s) {
for (char *curr = s; *curr; ++curr)
*curr = toupper(*curr);
return s;
}
inline char *strLower(char *s) {
for (char *curr = s; *curr; ++curr)
*curr = tolower(*curr);
return s;
}
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,114 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/file.h"
#include "bagel/mfc/ifstream.h"
#include "bagel/mfc/global_functions.h"
namespace Bagel {
namespace MFC {
ifstream::ifstream() {
}
ifstream::ifstream(const char *filename, ios::openmode mode) {
open(filename, mode);
}
void ifstream::open(const char *filename, ios::openmode mode) {
_file = OpenFile(filename);
if (!_file)
error("Could not open - %s", filename);
}
bool ifstream::is_open() const {
return _file;
}
void ifstream::close() {
delete _file;
_file = nullptr;
}
ifstream &ifstream::getline(char *buffer, size_t count) {
char c;
_cCount = 0;
while (!_file->eos()) {
c = _file->readByte();
// Check for end of line characters
if (c == '\n')
break;
if (c == '\r') {
c = _file->readByte();
assert(c == '\n');
break;
}
*buffer++ = c;
++_cCount;
}
*buffer = '\0';
return *this;
}
ifstream &ifstream::read(char *buffer, size_t count) {
_cCount = _file->read(buffer, count);
return *this;
}
size_t ifstream::gcount() const {
return _cCount;
}
bool ifstream::good() const {
return !_file->err();
}
bool ifstream::eof() const {
return _file->eos();
}
bool ifstream::ifstream::fail() const {
return _file->err();
}
bool ifstream::ifstream::bad() const {
return _file->err();
}
size_t ifstream::tellg() {
return _file->pos();
}
ifstream &ifstream::seekg(size_t pos) {
_file->seek(pos);
return *this;
}
ifstream &ifstream::seekg(int32 off, int dir) {
_file->seek(off, dir);
return *this;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,71 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_IFSTREAM_H
#define BAGEL_MFC_IFSTREAM_H
#include "common/file.h"
namespace Bagel {
namespace MFC {
namespace ios {
enum openmode {
in = 1 << 0,
binary = 1 << 1
};
} // namespace ios
class ifstream {
private:
Common::SeekableReadStream *_file = nullptr;
size_t _cCount = 0;
public:
ifstream();
ifstream(const char *filename, ios::openmode mode = ios::in);
virtual ~ifstream() {
close();
}
virtual void open(const char *filename, ios::openmode mode = ios::in);
virtual bool is_open() const;
virtual void close();
virtual ifstream &getline(char *buffer, size_t count);
virtual ifstream &read(char *buffer, size_t count);
virtual size_t gcount() const;
virtual bool good() const;
virtual bool eof() const;
virtual bool fail() const;
virtual bool bad() const;
// Positioning
virtual size_t tellg();
virtual ifstream &seekg(size_t pos);
virtual ifstream &seekg(int32 off, int dir);
};
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,47 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/joystickapi.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
MMRESULT joySetCapture(HWND hwnd, unsigned int uJoyID,
unsigned int uPeriod, bool fChanged) {
return AfxGetApp()->joySetCapture(hwnd, uJoyID, uPeriod, fChanged);
}
MMRESULT joySetThreshold(unsigned int uJoyID, unsigned int uThreshold) {
return AfxGetApp()->joySetThreshold(uJoyID, uThreshold);
}
MMRESULT joyGetPos(unsigned int uJoyID, LPJOYINFO pji) {
return AfxGetApp()->joyGetPos(uJoyID, pji);
}
MMRESULT joyReleaseCapture(unsigned int uJoyID) {
return AfxGetApp()->joyReleaseCapture(uJoyID);
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_JOYSTICKAPI_H
#define BAGEL_MFC_JOYSTICKAPI_H
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/winnt.h"
namespace Bagel {
namespace MFC {
typedef int MMRESULT;
/* joystick ID constants */
#define JOYSTICKID1 0
#define JOYSTICKID2 1
/* constants used with JOYINFO and JOYINFOEX structures and MM_JOY* messages */
#define JOY_BUTTON1 0x0001
#define JOY_BUTTON2 0x0002
#define JOY_BUTTON3 0x0004
#define JOY_BUTTON4 0x0008
#define JOY_BUTTON1CHG 0x0100
#define JOY_BUTTON2CHG 0x0200
#define JOY_BUTTON3CHG 0x0400
#define JOY_BUTTON4CHG 0x0800
/* joystick error return values */
#define JOYERR_NOERROR (0) /* no error */
#define JOYERR_PARMS (JOYERR_BASE+5) /* bad parameters */
#define JOYERR_NOCANDO (JOYERR_BASE+6) /* request not completed */
#define JOYERR_UNPLUGGED (JOYERR_BASE+7) /* joystick is unplugged */
/* joystick information data structure */
typedef struct joyinfo_tag {
unsigned int wXpos; /* x position */
unsigned int wYpos; /* y position */
unsigned int wZpos; /* z position */
unsigned int wButtons; /* button states */
} JOYINFO, *PJOYINFO, NEAR *NPJOYINFO, FAR *LPJOYINFO;
extern MMRESULT joySetCapture(HWND hwnd,
unsigned int uJoyID, unsigned int uPeriod, bool fChanged);
extern MMRESULT joySetThreshold(unsigned int uJoyID, unsigned int uThreshold);
extern MMRESULT joyGetPos(unsigned int uJoyID, LPJOYINFO pji);
extern MMRESULT joyReleaseCapture(unsigned int uJoyID);
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,63 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_KEYBOARD_H
#define BAGEL_MFC_KEYBOARD_H
#include "common/events.h"
namespace Bagel {
namespace MFC {
enum {
VK_UP = Common::KEYCODE_UP,
VK_DOWN = Common::KEYCODE_DOWN, // go to next page of text
VK_LEFT = Common::KEYCODE_LEFT,
VK_RIGHT = Common::KEYCODE_RIGHT,
VK_NUMPAD1 = Common::KEYCODE_KP1,
VK_NUMPAD2 = Common::KEYCODE_KP2,
VK_NUMPAD3 = Common::KEYCODE_KP3,
VK_NUMPAD4 = Common::KEYCODE_KP4,
VK_NUMPAD5 = Common::KEYCODE_KP5,
VK_NUMPAD6 = Common::KEYCODE_KP6,
VK_NUMPAD7 = Common::KEYCODE_KP7,
VK_NUMPAD8 = Common::KEYCODE_KP8,
VK_NUMPAD9 = Common::KEYCODE_KP9,
VK_PRIOR = Common::KEYCODE_PAGEUP,
VK_NEXT = Common::KEYCODE_PAGEDOWN,
VK_HOME = Common::KEYCODE_HOME,
VK_END = Common::KEYCODE_END,
VK_BACK = Common::KEYCODE_BACKSPACE,
VK_SCROLL = Common::KEYCODE_SCROLLOCK,
VK_F1 = Common::KEYCODE_F1,
VK_F2 = Common::KEYCODE_F2,
VK_F3 = Common::KEYCODE_F3,
VK_F4 = Common::KEYCODE_F4,
VK_F8 = Common::KEYCODE_F8,
VK_RETURN = Common::KEYCODE_RETURN,
VK_ESCAPE = Common::KEYCODE_ESCAPE,
VK_SPACE = Common::KEYCODE_SPACE
};
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,74 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_LIBS_ARRAY_H
#define BAGEL_MFC_LIBS_ARRAY_H
#include "common/array.h"
namespace Bagel {
namespace MFC {
namespace Libs {
template<class T>
class Array : public Common::Array<T> {
public:
constexpr Array() : Common::Array<T>() {
}
explicit Array(size_t count) : Common::Array<T>(count) {
}
Array(size_t count, const T &value) :
Common::Array<T>(count, value) {
}
Array(const Common::Array<T> &array) : Common::Array<T>(array) {
}
Array(Common::Array<T> &&old) : Common::Array<T>(old) {
}
Array(std::initializer_list<T> list) : Common::Array<T>(list) {
}
template<class T2>
Array(const T2 *array, size_t n) :
Common::Array<T>(array, n) {
}
int indexOf(const T &value) const {
for (int i = 0; i < (int)this->size(); ++i) {
if (this->operator[](i) == value)
return i;
}
return -1;
}
bool remove(const T &value) {
int idx = this->indexOf(value);
if (idx != -1)
this->remove_at(idx);
return idx != -1;
}
bool contains(const T &value) const {
return this->indexOf(value) != -1;
}
};
} // namespace Libs
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,551 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/system.h"
#include "engines/engine.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/libs/event_loop.h"
#include "bagel/mfc/winnt.h"
namespace Bagel {
namespace MFC {
namespace Libs {
#define FRAME_RATE 50
void EventLoop::runEventLoop(bool isModalDialog) {
MSG msg;
while (!shouldQuit() && !_activeWindows.empty()) {
CWnd *activeWin = GetActiveWindow();
if (activeWin->_modalResult != DEFAULT_MODAL_RESULT)
break;
if (!GetMessage(msg))
break;
CWnd *mainWnd = GetActiveWindow();
if (msg.message != WM_NULL && mainWnd && !mainWnd->PreTranslateMessage(&msg) &&
(!isModalDialog || !mainWnd->IsDialogMessage(&msg))) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
void EventLoop::SetActiveWindow(CWnd *wnd) {
assert(!shouldQuit());
if (wnd == GetActiveWindow())
// Already the active window
return;
// If it's the first window added, and we don't have
// a main window defined, set it as the main window
if (_activeWindows.empty())
_mainWindow = wnd;
// Add the window to the list
// Note: Currently we don't supportly multiple
// open windows at the same time. Each new window
// is effectively a dialog on top of previous ones
if (!_activeWindows.empty()) {
auto *win = _activeWindows.top();
win->SendMessage(WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), 0);
win->SendMessage(WM_PALETTECHANGED, (WPARAM)wnd);
}
_activeWindows.push(wnd);
wnd->SendMessage(WM_ACTIVATE, MAKEWPARAM(WA_ACTIVE, 0), 0);
wnd->SendMessage(WM_QUERYNEWPALETTE, 0, 0);
}
void EventLoop::PopActiveWindow() {
_activeWindows.top()->SendMessage(WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), 0);
_activeWindows.pop();
if (!_activeWindows.empty()) {
CWnd *wnd = _activeWindows.top();
wnd->RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_ALLCHILDREN);
wnd->SendMessage(WM_ACTIVATE, MAKEWPARAM(WA_ACTIVE, 0), 0);
}
}
void EventLoop::doModal(CWnd *wnd) {
SetActiveWindow(wnd);
runEventLoop(true);
if (GetActiveWindow() == wnd)
wnd->DestroyWindow();
}
void EventLoop::checkMessages() {
// Don't do any actual ScummVM event handling
// until at least one window has been set up
if (_activeWindows.empty())
return;
if (_messages.empty() && _idleCtr >= 0) {
if (!OnIdle(_idleCtr))
// OnIdle returning false means disabling permanently
_idleCtr = -1;
}
// Poll for event in ScummVM event manager
MSG priorMsg;
Libs::Event ev;
while (pollEvents(ev)) {
// Handle custom keybinding actions mapping back to keys
if (_keybindProc) {
if (ev.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
ev.type = Common::EVENT_KEYDOWN;
ev.kbd.keycode = _keybindProc(ev.customType);
} else if (ev.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
ev.type = Common::EVENT_KEYUP;
ev.kbd.keycode = _keybindProc(ev.customType);
}
}
HWND hWnd = nullptr;
setMessageWnd(ev, hWnd);
MSG msg = ev;
msg.hwnd = hWnd;
if (msg.message == WM_MOUSEMOVE &&
priorMsg.message == WM_MOUSEMOVE) {
// Preventing multiple sequential mouse move messages
priorMsg = msg;
} else if (msg.message != WM_NULL) {
if (priorMsg.message != WM_NULL)
_messages.push(priorMsg);
priorMsg = msg;
}
if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) {
// Update saved mouse position
_mousePos.x = LOWORD(msg.lParam);
_mousePos.y = HIWORD(msg.lParam);
// For mouse messages, if the highlighted control
// changes, generate a WM_SETCURSOR event
if (msg.hwnd != _highlightedWin) {
// Add mouse leave event if win is still alive
CWnd *highlightedWin = CWnd::FromHandle(_highlightedWin);
if (highlightedWin)
highlightedWin->PostMessage(WM_MOUSELEAVE);
// Switch to newly highlighted control
_highlightedWin = msg.hwnd;
if (_highlightedWin)
PostMessage(_highlightedWin,
WM_SETCURSOR, (WPARAM)msg.hwnd,
MAKELPARAM(HTCLIENT, msg.message)
);
}
} else if (msg.message == WM_QUIT) {
// Add a window message close message as well
MSG cmsg;
cmsg.message = WM_CLOSE;
cmsg.hwnd = hWnd;
_messages.push(cmsg);
}
}
if (priorMsg.message != WM_NULL)
_messages.push(priorMsg);
// If there are no pending messages,
// do a brief pause and check for frame updates
if (_messages.empty())
checkForFrameUpdate();
}
bool EventLoop::GetMessage(MSG &msg) {
checkMessages();
// Queue window/control repaints if needed
for (CWnd *wnd : _updateWnds) {
if (wnd->IsWindowDirty())
wnd->PostMessage(WM_PAINT);
}
_updateWnds.clear();
// Check for any existing messages
if (!_messages.empty()) {
msg = _messages.pop();
if (msg.hwnd) {
if ((msg.message == WM_KEYDOWN || msg.message == WM_KEYUP) &&
!_kbdHookProc.empty()) {
if (_kbdHookProc.front()(HC_ACTION, msg.wParam, msg.lParam))
msg.message = WM_NULL;
}
} else if (msg.message != WM_QUIT) {
msg.message = WM_NULL;
} else {
debug(1, "Got WM_QUIT message..");
}
} else {
msg.message = WM_NULL;
}
return !((msg.message == WM_QUIT) || (shouldQuit() && _messages.empty()));
}
void EventLoop::setMessageWnd(Common::Event &ev, HWND &hWnd) {
if (isMouseMsg(ev)) {
setMouseMessageWnd(ev, hWnd);
return;
}
if (_focusedWin && (ev.type == Common::EVENT_KEYDOWN ||
ev.type == Common::EVENT_KEYUP)) {
hWnd = _focusedWin->m_hWnd;
return;
}
if (isJoystickMsg(ev)) {
CWnd *joystickWin = CWnd::FromHandle(_joystickWin);
if (joystickWin) {
switch (ev.type) {
case Common::EVENT_JOYAXIS_MOTION:
if (ev.joystick.axis == 0)
_joystickPos.x = ev.joystick.position + JOYSTICK_REST_POS;
else
_joystickPos.y = ev.joystick.position + JOYSTICK_REST_POS;
joystickWin->SendMessage(MM_JOY1MOVE, JOYSTICKID1,
MAKELPARAM(_joystickPos.x, _joystickPos.y));
break;
default:
_joystickButtons = ev.joystick.button;
_joystickWin->SendMessage(MM_JOY1MOVE, JOYSTICKID1,
MAKELPARAM(_joystickPos.x, _joystickPos.y));
break;
}
}
hWnd = nullptr;
return;
}
// Fallback, send message to active window
CWnd *activeWin = _activeWindows.top();
hWnd = activeWin->m_hWnd;
}
void EventLoop::setMouseMessageWnd(Common::Event &ev, HWND &hWnd) {
// Handle mouse capture
if (_captureWin) {
hWnd = _captureWin->m_hWnd;
POINT pt;
pt.x = ev.mouse.x;
pt.y = ev.mouse.y;
mousePosToClient(_captureWin, pt);
ev.mouse.x = pt.x;
ev.mouse.y = pt.y;
return;
}
// Special case for mouse moves: if there's an modal dialog,
// mouse moves will still be routed to the main window
// if the mouse is outside the dialog bounds
CWnd *activeWin = _activeWindows.top();
if (ev.type == Common::EVENT_MOUSEMOVE &&
!activeWin->_windowRect.contains(ev.mouse)) {
hWnd = _mainWindow->m_hWnd;
return;
}
CWnd *wnd = _activeWindows.top();
hWnd = getMouseMessageWnd(ev, wnd);
}
HWND EventLoop::getMouseMessageWnd(Common::Event &ev, CWnd *parent) {
POINT pt;
pt.x = ev.mouse.x;
pt.y = ev.mouse.y;
if (!mousePosToClient(parent, pt))
return nullptr;
// Iterate through any children
for (const auto &node : parent->getChildren()) {
HWND child = getMouseMessageWnd(ev, node._value);
if (child)
return child;
}
// Final control under mouse
ev.mouse.x = pt.x;
ev.mouse.y = pt.y;
return parent;
}
bool EventLoop::mousePosToClient(CWnd *wnd, POINT &pt) {
RECT clientRect;
// Get the mouse position in passed window
wnd->ScreenToClient(&pt);
wnd->GetClientRect(&clientRect);
Common::Rect r = clientRect;
return r.contains(pt.x, pt.y);
}
bool EventLoop::pollEvents(Common::Event &event) {
return g_system->getEventManager()->pollEvent(event);
}
void EventLoop::checkForFrameUpdate() {
// Brief pauses and screen updates
g_system->delayMillis(10);
// Trigger any pending timers
triggerTimers();
// Handle screen updates
uint32 time = g_system->getMillis();
if (time >= _nextFrameTime) {
_nextFrameTime = time + (1000 / FRAME_RATE);
AfxGetApp()->getScreen()->update();
}
// Cleanup any temporary handle wrapper
AfxGetApp()->AfxUnlockTempMaps();
}
bool EventLoop::PeekMessage(LPMSG lpMsg, HWND hWnd,
unsigned int wMsgFilterMin, unsigned int wMsgFilterMax,
unsigned int wRemoveMsg) {
checkMessages();
return _messages.peekMessage(lpMsg, hWnd,
wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
}
bool EventLoop::PostMessage(HWND hWnd, unsigned int Msg,
WPARAM wParam, LPARAM lParam) {
if (shouldQuit())
return false;
if (!hWnd && Msg == WM_PARENTNOTIFY)
// Hodj minigame launched directly without metagame,
// so we can ignore the WM_PARENTNOTIFY on closure
return false;
assert(hWnd);
_messages.push(MSG(hWnd, Msg, wParam, lParam));
return true;
}
void EventLoop::TranslateMessage(LPMSG lpMsg) {
if ((lpMsg->message == WM_KEYDOWN || lpMsg->message == WM_SYSKEYDOWN) &&
(isChar((Common::KeyCode)lpMsg->wParam) || Common::isPrint(lpMsg->_ascii))) {
uint message = (lpMsg->message == WM_SYSKEYDOWN) ?
WM_SYSCHAR : WM_CHAR;
WPARAM wParam = lpMsg->_ascii;
LPARAM lParam = lpMsg->lParam;
PostMessage(lpMsg->hwnd, message, wParam, lParam);
}
}
void EventLoop::DispatchMessage(LPMSG lpMsg) {
CWnd *wnd = CWnd::FromHandle(lpMsg->hwnd);
if (wnd) {
wnd->SendMessage(lpMsg->message,
lpMsg->wParam, lpMsg->lParam);
}
}
bool EventLoop::isMouseMsg(const Common::Event &ev) const {
return ev.type == Common::EVENT_MOUSEMOVE ||
ev.type == Common::EVENT_LBUTTONDOWN ||
ev.type == Common::EVENT_LBUTTONUP ||
ev.type == Common::EVENT_RBUTTONDOWN ||
ev.type == Common::EVENT_RBUTTONUP ||
ev.type == Common::EVENT_WHEELUP ||
ev.type == Common::EVENT_WHEELDOWN ||
ev.type == Common::EVENT_MBUTTONDOWN ||
ev.type == Common::EVENT_MBUTTONUP;;
}
bool EventLoop::isJoystickMsg(const Common::Event &ev) const {
return ev.type == Common::EVENT_JOYAXIS_MOTION ||
ev.type == Common::EVENT_JOYBUTTON_DOWN ||
ev.type == Common::EVENT_JOYBUTTON_UP;
}
bool EventLoop::shouldQuit() const {
return g_engine->shouldQuit();
}
void EventLoop::quit() {
g_engine->quitGame();
}
void EventLoop::SetCapture(HWND hWnd) {
_captureWin = hWnd;
}
void EventLoop::ReleaseCapture() {
_captureWin = nullptr;
}
HWND EventLoop::GetCapture() const {
return _captureWin;
}
void EventLoop::SetFocus(CWnd *wnd) {
HWND oldFocus = _focusedWin;
HWND newFocus = wnd ? wnd->m_hWnd : nullptr;
if (newFocus != _focusedWin) {
CWnd *focusedWin = CWnd::FromHandle(_focusedWin);
CWnd *newFocusedWin = CWnd::FromHandle(newFocus);
if (_focusChangeProc)
_focusChangeProc(focusedWin, newFocusedWin);
if (focusedWin) {
focusedWin->_hasFocus = false;
focusedWin->SendMessage(WM_KILLFOCUS,
wnd ? (WPARAM)newFocus : (WPARAM)nullptr);
}
_focusedWin = newFocus;
if (wnd) {
wnd->_hasFocus = true;
wnd->SendMessage(WM_SETFOCUS, (WPARAM)oldFocus);
}
}
}
void EventLoop::setMousePos(const Common::Point &pt) {
_mousePos = pt;
g_system->warpMouse(pt.x, pt.y);
}
MMRESULT EventLoop::joySetCapture(HWND hwnd, unsigned int uJoyID,
unsigned int uPeriod, bool fChanged) {
assert(uJoyID == JOYSTICKID1);
_joystickWin = hwnd;
return JOYERR_NOERROR;
}
MMRESULT EventLoop::joySetThreshold(unsigned int uJoyID, unsigned int uThreshold) {
// No implementation
return JOYERR_NOERROR;
}
MMRESULT EventLoop::joyGetPos(unsigned int uJoyID, LPJOYINFO pji) {
assert(uJoyID == JOYSTICKID1);
pji->wXpos = _joystickPos.x;
pji->wYpos = _joystickPos.y;
pji->wZpos = 0;
pji->wButtons = _joystickButtons;
return JOYERR_NOERROR;
}
MMRESULT EventLoop::joyReleaseCapture(unsigned int uJoyID) {
assert(uJoyID == JOYSTICKID1);
return JOYERR_NOERROR;
}
uintptr EventLoop::SetTimer(HWND hWnd, uintptr nIDEvent, unsigned int nElapse,
void (CALLBACK *lpfnTimer)(HWND, unsigned int, uintptr, uint32)) {
if (!nIDEvent)
nIDEvent = ++_timerIdCtr;
_timers.push_back(TimerEntry(hWnd, nIDEvent, nElapse, lpfnTimer));
return nIDEvent;
}
bool EventLoop::KillTimer(HWND hWnd, uintptr nIDEvent) {
for (auto it = _timers.begin(); it != _timers.end(); ++it) {
if (it->_hWnd == hWnd && it->_idEvent == nIDEvent) {
_timers.erase(it);
return true;
}
}
return false;
}
void EventLoop::triggerTimers() {
uint32 currTime = g_system->getMillis();
for (auto it = _timers.begin(); it != _timers.end(); ) {
if (currTime >= it->_nextTriggerTime) {
// First update the timer for the next time
it->_nextTriggerTime = currTime + it->_interval;
if (it->_callback) {
// Call the callback
it->_callback(it->_hWnd, WM_TIMER, it->_idEvent, currTime);
} else {
// Otherwise, send timer event
CWnd *wnd = CWnd::FromHandle(it->_hWnd);
if (wnd)
wnd->SendMessage(WM_TIMER, it->_idEvent, 0);
}
// Since it's conceivable that a timer callback might
// remove timers, always restart the iterator afterwards
it = _timers.begin();
} else {
++it;
}
}
}
EventLoop::TimerEntry::TimerEntry(HWND hWnd, uintptr idEvent,
uint32 interval, TimerProc callback) :
_hWnd(hWnd), _idEvent(idEvent),
_interval(interval), _callback(callback) {
_nextTriggerTime = g_system->getMillis() + interval;
}
void EventLoop::pause() {
// Pause and update screen
g_system->delayMillis(20);
AfxGetApp()->getScreen()->update();
AfxGetApp()->checkMessages();
}
bool EventLoop::isChar(Common::KeyCode kc) const {
return kc == Common::KEYCODE_SPACE ||
kc == Common::KEYCODE_TAB ||
kc == Common::KEYCODE_RETURN ||
kc == Common::KEYCODE_BACKSPACE ||
kc == Common::KEYCODE_ESCAPE;
}
} // namespace Libs
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,270 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_LIBS_EVENT_LOOP_H
#define BAGEL_MFC_LIBS_EVENT_LOOP_H
#include "common/events.h"
#include "common/list.h"
#include "common/stack.h"
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/libs/events.h"
#include "bagel/mfc/joystickapi.h"
namespace Bagel {
namespace MFC {
namespace Libs {
typedef void(*TimerProc)(
HWND hwnd, // handle of window associated with the timer (can be NULL)
unsigned int uMsg, // WM_TIMER message (always WM_TIMER)
uintptr idEvent,// timer identifier (from SetTimer or returned value)
uint32 dwTime // system time when the callback was called (in milliseconds)
);
typedef Common::KeyCode(*KeybindProc)(int key);
typedef void (*FocusChangeProc)(CWnd *oldFocus, CWnd *newFocus);
#define JOYSTICK_REST_POS 32767
class WndList : public Common::List<CWnd *> {
public:
bool contains(CWnd *wnd) const {
for (auto it = begin(); it != end(); ++it) {
if (*it == wnd)
return true;
}
return false;
}
void add(CWnd *wnd) {
if (!contains(wnd))
push_back(wnd);
}
void remove(CWnd *wnd) {
Common::List<CWnd *>::remove(wnd);
}
void clear() {
Common::List<CWnd *>::clear();
}
};
class EventLoop {
struct TimerEntry {
HWND _hWnd = nullptr;
uintptr _idEvent = 0;
uint32 _interval = 0;
uint32 _nextTriggerTime = 0;
TimerProc _callback = nullptr;
TimerEntry() {}
TimerEntry(HWND hWnd, uintptr idEvent,
uint32 interval, TimerProc callback);
};
typedef Common::List<TimerEntry> TimerList;
private:
CWnd *_mainWindow = nullptr;
Common::Stack<CWnd *> _activeWindows;
WndList _updateWnds;
HWND _highlightedWin = nullptr;
HWND _captureWin = nullptr;
HWND _focusedWin = nullptr;
HWND _joystickWin = nullptr;
Libs::EventQueue _messages;
TimerList _timers;
int _timerIdCtr = 0;
uint32 _nextFrameTime = 0;
Common::Point _joystickPos = { JOYSTICK_REST_POS, JOYSTICK_REST_POS };
Common::Point _mousePos;
uint _joystickButtons = 0;
Array<HOOKPROC> _kbdHookProc;
int _idleCtr = 0;
KeybindProc _keybindProc = nullptr;
FocusChangeProc _focusChangeProc = nullptr;
private:
/**
* Get any pending event
* @return Returns false if app should quit
*/
bool GetMessage(MSG &msg);
/**
* Gets the destination window for a message
*/
void setMessageWnd(Common::Event &ev, HWND &hWnd);
/**
* Determine the window to send a mouse message to,
* and translates the event mouse position to be
* relative to the control's client rect
*/
void setMouseMessageWnd(Common::Event &ev, HWND &hWnd);
HWND getMouseMessageWnd(Common::Event &ev, CWnd *parent);
/**
* Returns true if the event is mouse related
*/
bool isMouseMsg(const Common::Event &ev) const;
/**
* Returns true if the event is joystick related
*/
bool isJoystickMsg(const Common::Event &ev) const;
/**
* Converts a position to be relative to a given window
*/
bool mousePosToClient(CWnd *wnd, POINT &pt);
/**
* Trigger any pending timers
*/
void triggerTimers();
/**
* Returns true if a keycode is one that
* generates a WM_CHAR or WM_SYSCHAR event
*/
bool isChar(Common::KeyCode kc) const;
/**
* Called when there are no pending messages.
* Handles screen frame updates and timers
*/
void checkForFrameUpdate();
public:
EventLoop() {}
virtual ~EventLoop() {}
void runEventLoop(bool isModalDialog);
void SetActiveWindow(CWnd *wnd);
void PopActiveWindow();
CWnd *GetActiveWindow() const {
return _activeWindows.empty() ? nullptr :
_activeWindows.top();
}
/**
* Shows a modal dialog
*/
void doModal(CWnd *wnd);
/**
* Polls for any pending messages and adds
* them to the messages queue
*/
void checkMessages();
/**
* Polls the ScummVM backend for any pending events.
* Should be mostly only called internally by the main
* event loop, but there are rare cases, like in the
* Hodj n Podj movie window, where it was convenient to
* to call in a simplified event loop.
*/
bool pollEvents(Common::Event &event);
/**
* Checks the pending event queue for a message
* with the specified criteria.
*/
bool PeekMessage(LPMSG lpMsg, HWND hWnd,
unsigned int wMsgFilterMin, unsigned int wMsgFilterMax,
unsigned int wRemoveMsg);
bool PostMessage(HWND hWnd, unsigned int Msg,
WPARAM wParam, LPARAM lParam);
void TranslateMessage(LPMSG lpMsg);
void DispatchMessage(LPMSG lpMsg);
/**
* Returns whether the app should quit.
*/
bool shouldQuit() const;
/**
* Quit the game
*/
void quit();
void SetCapture(HWND hWnd);
void ReleaseCapture();
HWND GetCapture() const;
Common::Point getMousePos() const {
return _mousePos;
}
void setMousePos(const Common::Point &pt);
void SetFocus(CWnd *wnd);
CWnd *GetFocus() const {
return _focusedWin;
}
MMRESULT joySetCapture(HWND hwnd, unsigned int uJoyID,
unsigned int uPeriod, bool fChanged);
MMRESULT joySetThreshold(unsigned int uJoyID, unsigned int uThreshold);
MMRESULT joyGetPos(unsigned int uJoyID, LPJOYINFO pji);
MMRESULT joyReleaseCapture(unsigned int uJoyID);
HHOOK HookKeyboard(HOOKPROC proc) {
_kbdHookProc.push_back(proc);
return (HHOOK)proc;
}
void UnhookKeyboard(HHOOK hook) {
assert(_kbdHookProc.contains((HOOKPROC)hook));
_kbdHookProc.remove((HOOKPROC)hook);
}
uintptr SetTimer(HWND hWnd, uintptr nIDEvent, unsigned int nElapse,
void (CALLBACK *lpfnTimer)(HWND, unsigned int, uintptr, uint32));
bool KillTimer(HWND hWnd, uintptr nIDEvent);
void pause();
WndList &afxUpdateWnds() {
return _updateWnds;
}
virtual bool OnIdle(long lCount) {
return false;
}
void setKeybinder(KeybindProc proc) {
_keybindProc = proc;
}
void setFocusChangeProc(FocusChangeProc proc) {
_focusChangeProc = proc;
}
};
} // namespace Libs
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,190 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/system.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/libs/events.h"
namespace Bagel {
namespace MFC {
namespace Libs {
int Event::_flags;
int Event::_mouseX;
int Event::_mouseY;
void Event::init() {
_flags = 0;
_mouseX = _mouseY = 0;
}
Event::operator MSG() const {
MSG msg;
// Reset fields
msg.hwnd = (HWND)0;
msg.message = 0;
msg.wParam = msg.lParam = 0;
msg.time = g_system->getMillis();
// Handle quit messages
if (type == Common::EVENT_QUIT ||
type == Common::EVENT_RETURN_TO_LAUNCHER) {
msg.message = WM_QUIT;
return msg;
}
// For mouse events, set the position
if (type >= Common::EVENT_MOUSEMOVE &&
type <= Common::EVENT_MBUTTONUP) {
_mouseX = mouse.x;
_mouseY = mouse.y;
msg.lParam = MAKELPARAM(_mouseX, _mouseY);
switch (type) {
case Common::EVENT_LBUTTONDOWN:
_flags |= MK_LBUTTON;
break;
case Common::EVENT_LBUTTONUP:
_flags &= ~MK_LBUTTON;
break;
case Common::EVENT_RBUTTONDOWN:
_flags |= MK_RBUTTON;
break;
case Common::EVENT_RBUTTONUP:
_flags &= ~MK_RBUTTON;
break;
case Common::EVENT_MBUTTONDOWN:
_flags |= MK_MBUTTON;
break;
case Common::EVENT_MBUTTONUP:
_flags &= ~MK_MBUTTON;
break;
default:
break;
}
msg.wParam = _flags;
}
if (type == Common::EVENT_KEYDOWN ||
type == Common::EVENT_KEYUP) {
// Update flags
if (kbd.flags & Common::KBD_CTRL)
_flags |= MK_CONTROL;
else
_flags &= ~MK_CONTROL;
if (kbd.flags & Common::KBD_SHIFT)
_flags |= MK_SHIFT;
else
_flags &= ~MK_SHIFT;
}
switch (type) {
case Common::EVENT_KEYDOWN:
case Common::EVENT_KEYUP:
if (kbd.flags & Common::KBD_ALT)
msg.message = (type == Common::EVENT_KEYDOWN) ?
WM_SYSKEYDOWN : WM_SYSKEYUP;
else
msg.message = (type == Common::EVENT_KEYDOWN) ?
WM_KEYDOWN : WM_KEYUP;
msg.wParam = kbd.keycode;
msg.lParam = (kbdRepeat ? 1 : 0) |
((uint)kbd.keycode << 16) |
((kbd.keycode >= 256 ? 1 : 0) << 24) |
(((kbd.flags & Common::KBD_ALT) ? 1 : 0) << 29) |
((type == Common::EVENT_KEYUP ? 1 : 0) << 30) |
((type == Common::EVENT_KEYDOWN ? 1 : 0) << 31);
msg._kbdFlags = kbd.flags;
msg._ascii = kbd.ascii;
break;
case Common::EVENT_MOUSEMOVE:
msg.message = WM_MOUSEMOVE;
break;
case Common::EVENT_LBUTTONDOWN:
msg.message = WM_LBUTTONDOWN;
break;
case Common::EVENT_LBUTTONUP:
msg.message = WM_LBUTTONUP;
break;
case Common::EVENT_RBUTTONDOWN:
msg.message = WM_RBUTTONDOWN;
break;
case Common::EVENT_RBUTTONUP:
msg.message = WM_RBUTTONUP;
break;
case Common::EVENT_MBUTTONDOWN:
msg.message = WM_MBUTTONDOWN;
break;
case Common::EVENT_MBUTTONUP:
msg.message = WM_MBUTTONUP;
break;
default:
msg.message = WM_NULL;
break;
}
return msg;
}
/*--------------------------------------------*/
MSG EventQueue::pop() {
assert(!empty());
MSG result = _queue.back();
_queue.remove_at(_queue.size() - 1);
return result;
}
bool EventQueue::peekMessage(MSG *lpMsg, HWND hWnd,
unsigned int wMsgFilterMin, unsigned int wMsgFilterMax,
unsigned int wRemoveMsg) {
bool result = false;
for (uint i = 0; i < _queue.size(); ++i) {
const MSG &msg = _queue[i];
if ((hWnd == nullptr || hWnd == msg.hwnd) &&
((wMsgFilterMin == 0 && wMsgFilterMax == 0) ||
(msg.message == WM_QUIT) ||
(msg.message >= wMsgFilterMin && msg.message <= wMsgFilterMax))) {
// Found a matching message
*lpMsg = msg;
if (wRemoveMsg & PM_REMOVE)
// Remove the message
_queue.remove_at(i);
return true;
}
}
return result;
}
} // namespace Libs
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,82 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_LIBS_EVENTS_H
#define BAGEL_MFC_LIBS_EVENTS_H
#include "common/events.h"
#include "bagel/mfc/minwindef.h"
namespace Bagel {
namespace MFC {
namespace Libs {
class Event : public Common::Event {
private:
static int _mouseX, _mouseY;
static int _flags;
public:
static void init();
operator MSG() const;
};
class EventQueue {
private:
Common::Array<MSG> _queue;
public:
/**
* Returns true if the queue is empty
* @return true if empty
*/
bool empty() const {
return _queue.empty();
}
/**
* Adds a message to the queue
* @param msg Message to add
*/
void push(const MSG &msg) {
_queue.insert_at(0, msg);
}
/**
* Removes a message from the queue.
* @return
*/
MSG pop();
/**
* Checks the queue for a given message
*/
bool peekMessage(MSG *lpMsg, HWND hWnd,
unsigned int wMsgFilterMin, unsigned int wMsgFilterMax,
unsigned int wRemoveMsg);
};
} // namespace Libs
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,47 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_LIBS_LIST_H
#define BAGEL_MFC_LIBS_LIST_H
#include "common/list.h"
namespace Bagel {
namespace MFC {
namespace Libs {
template<class T>
class List : public Common::List<T> {
public:
bool contains(const T &tmp) const {
for (auto it = this->begin(); it != this->end(); ++it) {
if (*it == tmp)
return true;
}
return false;
}
};
} // namespace Libs
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,111 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/stream.h"
#include "common/formats/winexe_ne.h"
#include "bagel/mfc/libs/resources.h"
#include "bagel/mfc/global_functions.h"
namespace Bagel {
namespace MFC {
namespace Libs {
Resources::~Resources() {
clear();
}
void Resources::addResources(const Common::Path &file) {
Common::NEResources *res = new Common::NEResources();
if (!res->loadFromEXE(file))
error("Could not load %s", file.baseName().c_str());
push_front(ResourceFile());
front()._filename = file.baseName();
front()._res = res;
_cache.clear();
}
void Resources::removeResources(const Common::Path &file) {
// Expect resources to be removed in order
assert(file.baseName() == front()._filename);
pop_front();
_cache.clear();
}
HRSRC Resources::findResource(const char *lpName, const char *lpType) {
if (empty())
error("Use CWinApp::addResources to register "
"an .exe or .dll file containing the resources");
Common::WinResourceID type =
(HIWORD(lpType) == 0) ?
Common::WinResourceID((intptr)lpType) :
Common::WinResourceID(lpType);
Common::WinResourceID id;
if (HIWORD(lpName) == 0)
id = Common::WinResourceID((intptr)lpName);
else if (*lpName == '#')
id = Common::WinResourceID(atol(lpName + 1));
else
id = Common::WinResourceID(lpName);
// First check the cache
for (auto &it : _cache) {
if (it._type == type && it._id == id)
return (HRSRC)&it;
}
// Get the resource
for (auto &it : (*this)) {
Common::WinResources *res = it._res;
Common::SeekableReadStream *rs = res->getResource(type, id);
if (rs) {
// Add it to the cache, since we'll use
// a pointer to it's entry as the return
_cache.push_back(Resource(res, type, id, rs->size()));
delete rs;
return (HRSRC)&_cache.back();
}
}
return nullptr;
}
HGLOBAL Resources::loadResource(HRSRC hResInfo) {
Resource *ptr = ((Resource *)hResInfo);
Common::SeekableReadStream *rs = ptr->_file->getResource(
ptr->_type, ptr->_id);
HGLOBAL h = GlobalAlloc(GPTR, ptr->_size);
byte *data = (byte *)GlobalLock(h);
rs->read(data, ptr->_size);
GlobalUnlock(rs);
delete rs;
return h;
}
} // namespace Libs
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,104 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_LIBS_RESOURCES_H
#define BAGEL_MFC_LIBS_RESOURCES_H
#include "common/list.h"
#include "common/path.h"
#include "common/hashmap.h"
#include "common/formats/winexe.h"
#include "bagel/mfc/minwindef.h"
namespace Bagel {
namespace MFC {
namespace Libs {
struct Resource {
Common::WinResources *_file = nullptr;
Common::WinResourceID _type;
Common::WinResourceID _id;
size_t _size = 0;
Resource() {}
Resource(Common::WinResources *file,
const Common::WinResourceID &type,
Common::WinResourceID &id, size_t size) :
_file(file), _type(type), _id(id),
_size(size) {}
};
typedef Common::List<Resource> ResCache;
struct ResourceFile {
Common::String _filename;
Common::WinResources *_res = nullptr;
~ResourceFile() {
delete _res;
}
};
typedef Common::List<ResourceFile> ResList;
class Resources : public ResList {
private:
ResCache _cache;
public:
~Resources();
/**
* Adds a Windows file containing resources
*/
void addResources(const Common::Path &file);
/**
* Removes a Windows file containing resources
*/
void removeResources(const Common::Path &file);
#if 0
Common::WinResources *getCoreResources() const {
return _resources.begin()->_value;
}
#endif
/**
* Find a resource
*/
HRSRC findResource(const char *lpName, const char *lpType);
/**
* Return the size of a resource
*/
size_t resourceSize(HRSRC res) const {
return ((Resource *)res)->_size;
}
/**
* Return a resource as a memory block
*/
HGLOBAL loadResource(HRSRC hResInfo);
};
} // namespace Libs
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,146 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/system.h"
#include "engines/engine.h"
#include "bagel/mfc/libs/settings.h"
namespace Bagel {
namespace MFC {
namespace Libs {
Common::String Settings::getFilename() {
// Hack to get engine target name
Common::String fname = g_engine->getSaveStateName(0);
fname = Common::String(fname.c_str(), strchr(fname.c_str(), '.'));
fname += "-settings.ini";
return fname;
}
void Settings::load() {
Common::InSaveFile *src = g_system->getSavefileManager()->openForLoading(getFilename());
Common::String domainName;
if (src) {
while (!src->eos()) {
domainName = Domain::getDomainName(src);
if (domainName.empty())
break;
_domains[domainName].load(src);
}
}
delete src;
}
void Settings::save() {
if (_domains.empty() || !isModified())
return;
Common::OutSaveFile *dest = g_system->getSavefileManager()->openForSaving(getFilename(), false);
if (!dest)
return;
Common::String domainName;
for (Domains::iterator it = _domains.begin(); it != _domains.end(); ++it) {
if (it->_value.empty())
continue;
domainName = it->_key;
dest->writeByte('[');
dest->writeString(it->_key);
dest->writeByte(']');
dest->writeByte('\n');
it->_value.save(dest);
}
dest->finalize();
delete dest;
}
bool Settings::isModified() const {
for (Domains::iterator it = _domains.begin();
it != _domains.end(); ++it) {
if (it->_value.isModified())
return true;
}
return false;
}
Settings::Domain &Settings::operator[](const Common::String &domain) {
Settings::Domain &result = _domains[domain];
result._settings = this;
return result;
}
Common::String Settings::Domain::getDomainName(Common::InSaveFile *src) {
Common::String line = src->readLine();
if (line.empty())
return "";
assert(line.hasPrefix("[") && line.hasSuffix("]"));
return Common::String(line.c_str() + 1, line.size() - 2);
}
void Settings::Domain::load(Common::InSaveFile *src) {
Common::String str;
uint equals;
for (;;) {
str = src->readLine();
if (str.empty())
break;
equals = str.findFirstOf('=');
assert(equals != Common::String::npos);
_values[Common::String(str.c_str(),
str.c_str() + equals)] =
Common::String(str.c_str() + equals + 1);
}
}
void Settings::Domain::save(Common::OutSaveFile *dest) {
Common::String str;
for (Values::iterator it = _values.begin(); it != _values.end(); ++it) {
str = Common::String::format("%s=%s",
it->_key.c_str(), it->_value.c_str());
dest->writeString(str);
dest->writeByte('\n');
}
dest->writeByte('\n');
_modified = false;
}
void Settings::Domain::flushToDisk() {
assert(_settings);
_settings->save();
}
} // namespace Libs
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,141 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_LIBS_SETTINGS_H
#define BAGEL_MFC_LIBS_SETTINGS_H
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "common/savefile.h"
namespace Bagel {
namespace MFC {
namespace Libs {
class Settings {
public:
class Domain {
friend class Settings;
private:
typedef Common::HashMap<Common::String, Common::String,
Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> Values;
Settings *_settings = nullptr;
Values _values;
bool _modified = false;
public:
void load(Common::InSaveFile *src);
void save(Common::OutSaveFile *dest);
static Common::String getDomainName(Common::InSaveFile *src);
bool isModified() const {
return _modified;
}
bool empty() const {
return _values.empty();
}
bool hasKey(const Common::String &key) const {
return _values.contains(key);
}
int getInt(const Common::String &key, int defaultValue = 0) const {
return hasKey(key) ? atoi(_values[key].c_str()) : defaultValue;
}
bool getBool(const Common::String &key, bool defaultValue = false) const {
return !hasKey(key) || _values[key].empty() ? false :
tolower(_values[key][0]) == 't';
}
Common::String getString(const Common::String &key, const char *defaultValue = nullptr) const {
return hasKey(key) ? _values[key] : defaultValue;
}
void setInt(const Common::String &key, int value) {
_values[key] = Common::String::format("%d", value);
_modified = true;
}
void setBool(const Common::String &key, bool value) {
_values[key] = value ? "true" : "false";
_modified = true;
}
void setString(const Common::String &key, const Common::String &value) {
_values[key] = value;
_modified = true;
}
void flushToDisk();
};
class Serializer {
private:
Domain &_domain;
bool _isSaving;
public:
Serializer(Domain &domain, bool isSaving) :
_domain(domain), _isSaving(isSaving) {
}
~Serializer() {
_domain.flushToDisk();
}
void sync(const Common::String &key, int &field, int defaultValue = 0) {
if (_isSaving)
_domain.setInt(key, field);
else
field = _domain.getInt(key, defaultValue);
}
void sync(const Common::String &key, bool &field, bool defaultValue = false) {
if (_isSaving)
_domain.setBool(key, field);
else
field = _domain.getBool(key, defaultValue);
}
void sync(const Common::String &key, Common::String &field, const char *defaultValue = nullptr) {
if (_isSaving)
_domain.setString(key, field);
else
field = _domain.getString(key, defaultValue);
}
};
private:
static Common::String getFilename();
public:
~Settings() {
save();
}
void load();
void save();
bool isModified() const;
Domain &operator[](const Common::String &domain);
private:
typedef Common::HashMap<Common::String, Domain,
Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> Domains;
Domains _domains;
};
} // namespace Libs
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,33 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CListBox, CWnd)
BEGIN_MESSAGE_MAP(CListBox, CWnd)
END_MESSAGE_MAP()
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,60 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
CMenu::CMenu() {
}
bool CMenu::CreateMenu() {
error("TODO: CMenu::CreateMenu");
}
bool CMenu::CreatePopupMenu() {
error("TODO: CMenu::CreatePopupMenu");
}
bool CMenu::LoadMenu(const char *lpszResourceName) {
error("TODO: CMenu::LoadMenu");
}
bool CMenu::LoadMenu(unsigned int nIDResource) {
error("TODO: CMenu::LoadMenu");
}
bool CMenu::LoadMenuIndirect(const void *lpMenuTemplate) {
error("TODO: CMenu::LoadMenuIndirect");
}
bool CMenu::DestroyMenu() {
error("TODO: CMenu::DestroyMenu");
}
CMenu *CMenu::FromHandle(HMENU hMenu) {
error("TODO: CMenu::FromHandle");
}
unsigned int CMenu::CheckMenuItem(unsigned int nIDCheckItem, unsigned int nCheck) {
error("TODO: CMenu::CheckMenuItem");
}
} // namespace MFC
} // namespace Bagel

40
engines/bagel/mfc/mfc.h Normal file
View File

@@ -0,0 +1,40 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_MFC_H
#define BAGEL_MFC_MFC_H
#include "bagel/mfc/minwindef.h"
#include "bagel/mfc/winnt.h"
#include "bagel/mfc/wingdi.h"
#include "bagel/mfc/atltime.h"
#include "bagel/mfc/atltypes.h"
#include "bagel/mfc/afx.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/afxmsg.h"
#include "bagel/mfc/afxext.h"
#include "bagel/mfc/afxres.h"
#include "bagel/mfc/global_functions.h"
#include "bagel/mfc/ifstream.h"
#include "bagel/mfc/joystickapi.h"
#include "bagel/mfc/keyboard.h"
#endif

View File

@@ -0,0 +1,299 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_MINWINDEF_H
#define BAGEL_MFC_MINWINDEF_H
#include "common/scummsys.h"
#include "common/algorithm.h"
#include "common/rect.h"
#define WINVER 0
#include "bagel/mfc/winnt.h"
namespace Bagel {
namespace MFC {
#define ASSERT assert
#undef FAR
#undef NEAR
#define FAR
#define NEAR
#ifndef CONST
#define CONST const
#endif
#define CALLBACK
#define WINAPI
#define WINAPIV
#define APIENTRY WINAPI
#define APIPRIVATE
#define PASCAL
#define AFXAPI
#define AFX_DATA
#define AFX_NOVTABLE
#define BASED_CODE
#define AFX_CDECL
// We're temporary disabling virtual Create functions
// for ScummVM due to the warnings it generates
#define CVIRTUAL
#ifndef _In_
#define _In_
#endif
#ifndef _Out_
#define _Out_
#endif
#ifndef _In_z_
#define _In_z_
#endif
#ifndef _Inout_
#define _Inout_
#endif
// Dummy try/catch implementation
#define TRY if (1) {
#define END_TRY }
#define CATCH(KLASS, VAL) KLASS *VAL = nullptr; if (0)
#define END_CATCH }
DECLARE_HANDLE(HACCEL);
DECLARE_HANDLE(HCURSOR);
DECLARE_HANDLE(HDROP);
DECLARE_HANDLE(HHOOK);
DECLARE_HANDLE(HICON);
DECLARE_HANDLE(HMENU);
DECLARE_HANDLE(HRAWINPUT);
struct CGdiObjectImpl {
virtual ~CGdiObjectImpl() {};
};
typedef CGdiObjectImpl *HGDIOBJ;
typedef HGDIOBJ HBITMAP;
typedef HGDIOBJ HBRUSH;
typedef HGDIOBJ HFONT;
typedef HGDIOBJ HPALETTE;
typedef HGDIOBJ HPEN;
typedef HGDIOBJ HRGN;
typedef HGDIOBJ HENHMETAFILE;
typedef void *HDC;
class CWnd;
typedef CWnd *HWND;
/* Types use for passing & returning polymorphic values */
typedef uintptr WPARAM;
typedef intptr LPARAM;
typedef intptr LRESULT;
typedef LRESULT(CALLBACK *HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
typedef LRESULT(CALLBACK *WNDPROC)(HWND, unsigned int, WPARAM, LPARAM);
typedef intptr(FAR WINAPI *FARPROC)();
typedef intptr(NEAR WINAPI *NEARPROC)();
typedef intptr(WINAPI *PROC)();
typedef intptr(CALLBACK *DLGPROC)(HWND, unsigned int, WPARAM, LPARAM);
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define MAKEWORD(a, b) ((uint16)(((byte)(((uintptr)(a)) & 0xff)) | ((uint16)((byte)(((uintptr)(b)) & 0xff))) << 8))
#define MAKELONG(a, b) ((long)(((uint16)(((uintptr)(a)) & 0xffff)) | ((uint32)((uint16)(((uintptr)(b)) & 0xffff))) << 16))
#define LOWORD(l) ((uint16)(((uintptr)(l)) & 0xffff))
#define HIWORD(l) ((((uintptr)(l)) >> 16))
#define LOBYTE(w) ((byte)(((uintptr)(w)) & 0xff))
#define HIBYTE(w) ((byte)((((uintptr)(w)) >> 8) & 0xff))
#define POINTTOPOINTS(pt) (MAKELONG((short)((pt).x), (short)((pt).y)))
#define MAKEWPARAM(l, h) ((WPARAM)(uint32)MAKELONG(l, h))
#define MAKELPARAM(l, h) ((LPARAM)(uint32)MAKELONG(l, h))
#define MAKELRESULT(l, h) ((LRESULT)(uint32)MAKELONG(l, h))
typedef void *HANDLE;
typedef HANDLE NEAR *SPHANDLE;
typedef HANDLE FAR *LPHANDLE;
typedef HANDLE HGLOBAL;
typedef HANDLE HLOCAL;
typedef HANDLE GLOBALHANDLE;
typedef HANDLE LOCALHANDLE;
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
typedef uint16 ATOM; //BUGBUG - might want to remove this from minwin
DECLARE_HANDLE(HKEY);
typedef HKEY *PHKEY;
DECLARE_HANDLE(HMETAFILE);
DECLARE_HANDLE(HINSTANCE);
typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */
DECLARE_HANDLE(HRSRC);
DECLARE_HANDLE(HSPRITE);
DECLARE_HANDLE(HLSURF);
DECLARE_HANDLE(HSTR);
DECLARE_HANDLE(HTASK);
DECLARE_HANDLE(HWINSTA);
DECLARE_HANDLE(HKL);
typedef struct tagPOINT {
int x;
int y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
typedef struct tagSIZE {
int cx;
int cy;
} SIZE, *PSIZE, *LPSIZE;
typedef SIZE SIZEL;
typedef SIZE *PSIZEL, *LPSIZEL;
typedef struct tagPOINTS {
SHORT x;
SHORT y;
} POINTS, *PPOINTS, *LPPOINTS;
typedef struct tagRECT {
int left;
int top;
int right;
int bottom;
operator Common::Rect() const {
return Common::Rect(left, top, right, bottom);
}
bool contains(int x, int y) const {
Common::Rect r = *this;
return r.contains(x, y);
}
bool contains(const POINT &pt) const {
Common::Rect r = *this;
return r.contains(pt.x, pt.y);
}
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
typedef const RECT FAR *LPCRECT;
inline Common::Rect RECTtoRect(const RECT &src) {
return src;
}
inline RECT RectToRECT(const Common::Rect &src) {
RECT dest;
dest.left = src.left;
dest.top = src.top;
dest.right = src.right;
dest.bottom = src.bottom;
return dest;
}
inline RECT RectToRECT(int x1, int y1, int x2, int y2) {
RECT dest;
dest.left = x1;
dest.top = y1;
dest.right = x2;
dest.bottom = y2;
return dest;
}
inline bool RectsIntersect(const RECT &r1, const RECT &r2) {
return RECTtoRect(r1).intersects(RECTtoRect(r2));
}
typedef struct _FILETIME {
uint32 dwLowDateTime;
uint32 dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
typedef struct _SYSTEMTIME {
uint16 wYear;
uint16 wMonth;
uint16 wDayOfWeek;
uint16 wDay;
uint16 wHour;
uint16 wMinute;
uint16 wSecond;
uint16 wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
typedef struct tagPAINTSTRUCT {
HDC hdc;
bool fErase;
RECT rcPaint;
bool fRestore;
bool fIncUpdate;
byte rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;
/*
* Message structure
*/
typedef struct tagMSG {
HWND hwnd = 0;
unsigned int message = 0;
WPARAM wParam = 0;
LPARAM lParam = 0;
uint32 time = 0;
POINT pt;
// Extra fields for TranslateMessage convenience
byte _kbdFlags = 0;
char _ascii = 0;
tagMSG() {
pt.x = pt.y = 0;
}
tagMSG(HWND hwnd_, unsigned int message_, WPARAM wParam_ = 0,
LPARAM lParam_ = 0) :
hwnd(hwnd_), message(message_), wParam(wParam_),
lParam(lParam_) {
pt.x = pt.y = 0;
}
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
inline bool PtInRect(const RECT *lprc, const POINT &pt) {
return pt.x >= lprc->left && pt.x < lprc->right &&
pt.y >= lprc->top && pt.y < lprc->bottom;
}
typedef struct tagWNDCLASS {
unsigned int style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
const char * lpszMenuName;
const char * lpszClassName;
} WNDCLASS, *PWNDCLASS, *NPWNDCLASS, *LPWNDCLASS;
struct CDataExchange {
bool m_bSaveAndValidate;
};
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,49 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/mfc/mfc.h"
namespace Bagel {
namespace MFC {
const CRuntimeClass CObject::classCObject = {
"CObject", sizeof(CObject), 0xFFFF, // class name, size, schema
nullptr, // (null if DECLARE_DYNAMIC only)
nullptr // pointer to base class's CRuntimeClass
};
CObject::CObject() {
}
CObject::~CObject() {
}
const CRuntimeClass *CObject::GetRuntimeClass() const {
return &CObject::classCObject;
}
bool CObject::IsKindOf(const CRuntimeClass *pClass) const {
const CRuntimeClass *pClassThis = GetRuntimeClass();
return pClassThis->IsDerivedFrom(pClass);
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,43 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CPaintDC, CDC)
CPaintDC::CPaintDC(CWnd *pWnd) {
m_hWnd = pWnd->m_hWnd;
if (!Attach(MFC::BeginPaint(m_hWnd, &m_ps)))
error("Could not attach to window");
}
CPaintDC::~CPaintDC() {
MFC::EndPaint(m_hWnd, &m_ps);
Detach();
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,140 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
bool CPalette::CreatePalette(LPLOGPALETTE lpLogPalette) {
DeleteObject();
m_hObject = new Impl(lpLogPalette);
// This is where it becomes permanent
AfxHookObject();
return true;
}
int CPalette::GetObject(int nCount, void *lpObject) const {
LOGPALETTE *pal = (LOGPALETTE *)lpObject;
const Impl *src = static_cast<const Impl *>(m_hObject);
assert(nCount >= 4);
pal->palVersion = 0x300;
nCount -= 2;
pal->palNumEntries = src->size();
nCount -= 2;
uint i;
for (i = 0; i < src->size() && nCount > 0; ++i, nCount -= 4) {
auto &entry = pal->palPalEntry[i];
src->get(i, entry.peRed, entry.peGreen, entry.peBlue);
entry.peFlags = 0;
}
return 4 + (4 * i);
}
unsigned int CPalette::GetEntryCount() const {
const Impl *src = static_cast<const Impl *>(m_hObject);
return src->size();
}
unsigned int CPalette::GetPaletteEntries(unsigned int nStartIndex, unsigned int nNumEntries,
LPPALETTEENTRY lpPaletteColors) const {
const Impl *src = static_cast<const Impl *>(m_hObject);
for (uint i = 0; i < nNumEntries; ++i) {
auto &entry = lpPaletteColors[i];
src->get(nStartIndex + i, entry.peRed,
entry.peGreen, entry.peBlue);
entry.peFlags = 0;
}
return src->size();
}
unsigned int CPalette::SetPaletteEntries(unsigned int nStartIndex, unsigned int nNumEntries,
LPPALETTEENTRY lpPaletteColors) {
Impl *pal = static_cast<Impl *>(m_hObject);
for (uint i = 0; i < nNumEntries; ++i) {
auto &entry = lpPaletteColors[i];
pal->set(nStartIndex + i, entry.peRed,
entry.peGreen, entry.peBlue);
}
return nNumEntries;
}
unsigned int CPalette::SetPaletteEntries(const Graphics::Palette &pal) {
DeleteObject();
m_hObject = new Impl(pal);
// This is where it becomes permanent
AfxHookObject();
return pal.size();
}
bool CPalette::AnimatePalette(unsigned int nStartIndex, unsigned int nNumEntries,
const PALETTEENTRY *lpPaletteColors) {
// Set the new colors
Graphics::Palette *impl = static_cast<Impl *>(m_hObject);
for (; nNumEntries > 0; ++nStartIndex, --nNumEntries,
++lpPaletteColors) {
impl->set(nStartIndex, lpPaletteColors->peRed,
lpPaletteColors->peGreen,
lpPaletteColors->peBlue);
}
// Set the new system palette
AfxGetApp()->setPalette(*impl);
return true;
}
unsigned int CPalette::GetNearestPaletteIndex(COLORREF crColor) {
return palette()->findBestColor(
GetRValue(crColor),
GetGValue(crColor),
GetBValue(crColor)
);
}
/*--------------------------------------------*/
CPalette::Impl::Impl(const LPLOGPALETTE pal) :
CGdiObjectImpl(), Graphics::Palette(pal->palNumEntries) {
for (uint i = 0; i < size(); ++i) {
const auto &e = pal->palPalEntry[i];
set(i, e.peRed, e.peGreen, e.peBlue);
}
}
CPalette::Impl::Impl(const Graphics::Palette &pal) :
CGdiObjectImpl(), Graphics::Palette(pal) {
}
} // namespace MFC
} // namespace Bagel

39
engines/bagel/mfc/pen.cpp Normal file
View File

@@ -0,0 +1,39 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
CPen::CPen(int nPenStyle, int nWidth, COLORREF crColor) {
CreatePen(nPenStyle, nWidth, crColor);
}
bool CPen::CreatePen(int nPenStyle, int nWidth, COLORREF crColor) {
m_hObject = new Impl(nPenStyle, nWidth, crColor);
AfxHookObject();
return true;
}
} // namespace MFC
} // namespace Bagel

49
engines/bagel/mfc/rgn.cpp Normal file
View File

@@ -0,0 +1,49 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
bool CRgn::CreateRectRgn(int x1, int y1, int x2, int y2) {
_rect = Common::Rect(x1, y1, x2, y2);
return true;
}
bool CRgn::CreateRectRgnIndirect(LPCRECT lpRect) {
_rect = Common::Rect(lpRect->left, lpRect->top,
lpRect->right, lpRect->bottom);
return true;
}
bool CRgn::CreatePolygonRgn(const POINT *lpPoints,
int nCount, int nPolyFillMode) {
for (; nCount > 0; ++lpPoints, --nCount)
_points.push_back(*lpPoints);
_polyFillMode = nPolyFillMode;
return true;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,40 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CScrollView, CView)
BEGIN_MESSAGE_MAP(CScrollView, CView)
END_MESSAGE_MAP()
const SIZE CScrollView::sizeNull = { 0, 0 };
void CScrollView::SetScrollSizes(int nMapMode, SIZE sizeTotal,
const SIZE &sizePage, const SIZE &sizeLine) {
error("TODO: CScrollView::SetScrollSizes");
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,245 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CScrollBar, CWnd)
BEGIN_MESSAGE_MAP(CScrollBar, CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
END_MESSAGE_MAP()
bool CScrollBar::Create(uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID) {
return CWnd::Create("SCROLLBAR", nullptr, dwStyle,
rect, pParentWnd, nID);
}
int CScrollBar::GetScrollPos() const {
return _value;
}
int CScrollBar::SetScrollPos(int nPos, bool bRedraw) {
int oldPos = _value;
_value = CLIP(nPos, _minValue, _maxValue);
Invalidate();
return oldPos;
}
void CScrollBar::GetScrollRange(int *lpMinPos, int *lpMaxPos) const {
if (lpMinPos)
*lpMinPos = _minValue;
if (lpMaxPos)
*lpMaxPos = _maxValue;
}
void CScrollBar::SetScrollRange(int nMinPos, int nMaxPos, bool bRedraw) {
_minValue = nMinPos;
_maxValue = nMaxPos;
_pageSize = MAX<int>((_maxValue - _minValue + 1) / 10, 1);
Invalidate();
}
bool CScrollBar::SetScrollInfo(LPSCROLLINFO lpScrollInfo, bool bRedraw) {
assert(lpScrollInfo->cbSize == sizeof(SCROLLINFO));
_minValue = lpScrollInfo->nMin;
_maxValue = lpScrollInfo->nMax;
_pageSize = lpScrollInfo->nPage;
_value = lpScrollInfo->nPos;
if (bRedraw)
Invalidate();
return true;
}
void CScrollBar::ShowScrollBar(bool bShow) {
warning("TODO: CScrollBar::ShowScrollBar");
}
void CScrollBar::OnPaint() {
CPaintDC dc(this);
CRect clientRect;
GetClientRect(&clientRect);
const int thumbSize = clientRect.bottom;
// Clear background and draw border edge
dc.FillSolidRect(&clientRect, RGB(211, 211, 211));
CBrush borderBrush(RGB(0, 0, 0));
dc.FrameRect(&clientRect, &borderBrush);
CRect left(0, 0, thumbSize, clientRect.bottom);
drawSquare(dc, left);
drawArrow(dc, left, true);
CRect right(clientRect.right - thumbSize, 0,
clientRect.right, clientRect.bottom);
drawSquare(dc, right);
drawArrow(dc, right, false);
drawSquare(dc, getThumbRect());
}
void CScrollBar::drawSquare(CPaintDC &dc, const CRect &r) {
CBrush black(RGB(0, 0, 0));
dc.FrameRect(&r, &black);
CBrush darkGrey(RGB(169, 169, 169));
CBrush white(RGB(255, 255, 255));
CBrush *oldBrush = dc.SelectObject(&darkGrey);
dc.MoveTo(r.left + 2, r.bottom - 3);
dc.LineTo(r.right - 2, r.bottom - 3);
dc.MoveTo(r.left + 1, r.bottom - 2);
dc.LineTo(r.right - 2, r.bottom - 2);
dc.MoveTo(r.right - 3, r.top + 1);
dc.LineTo(r.right - 3, r.bottom - 2);
dc.MoveTo(r.right - 2, r.top + 1);
dc.LineTo(r.right - 2, r.bottom - 2);
dc.MoveTo(r.left + 1, r.top + 1);
dc.LineTo(r.right - 3, r.top + 1);
dc.MoveTo(r.left + 1, r.top + 1);
dc.MoveTo(r.left + 1, r.bottom - 3);
dc.SelectObject(oldBrush);
}
void CScrollBar::drawArrow(CPaintDC &dc, const CRect &r, bool leftArrow) {
int xCenter = (r.left + r.right) / 2;
int yCenter = r.bottom / 2;
int xDelta = leftArrow ? 1 : -1;
int x = leftArrow ? xCenter - 3 : xCenter + 3;
CBrush black(RGB(0, 0, 0));
CBrush *oldBrush = dc.SelectObject(&black);
for (int xCtr = 0; xCtr < 7; ++xCtr, x += xDelta) {
int yDiff = (xCtr >= 4) ? 1 : xCtr;
dc.MoveTo(x, yCenter - yDiff);
dc.LineTo(x, yCenter + yDiff);
}
dc.SelectObject(oldBrush);
}
CRect CScrollBar::getThumbRect() const {
CRect clientRect;
GetClientRect(&clientRect);
// The thumb will start after the left arrow button,
// and at most, it will be drawn before the right arrow
int slideArea = clientRect.right -
(clientRect.bottom * 3) + 1;
int xStart = clientRect.bottom +
slideArea * (_value - _minValue) /
(_maxValue - _minValue);
return CRect(xStart, 0, xStart + clientRect.bottom,
clientRect.bottom);
}
int CScrollBar::getIndexFromX(int xp) const {
CRect clientRect;
GetClientRect(&clientRect);
int slideStart = clientRect.bottom;
int slideFinish = clientRect.right - (clientRect.bottom * 2) + 1;
int slideArea = clientRect.right - (clientRect.bottom * 3) + 1;
if (xp < slideStart)
return _minValue;
if (xp >= slideFinish)
return _maxValue;
return _minValue + (xp - slideStart)
* (_maxValue - _minValue) / slideArea;
}
void CScrollBar::OnLButtonDown(unsigned int nFlags, CPoint point) {
CRect clientRect;
GetClientRect(&clientRect);
if (point.x < clientRect.bottom) {
// Left arrow button
if (_value > _minValue) {
SetScrollPos(_value - 1);
scrollEvent(SB_LINELEFT);
}
} else if (point.x >= (clientRect.right - clientRect.bottom)) {
// Right arrow button
if (_value < _maxValue) {
SetScrollPos(_value + 1);
scrollEvent(SB_LINERIGHT);
}
} else {
// We're in the slider area
CRect thumbRect = getThumbRect();
if (point.x < thumbRect.left) {
// Left of thumb, page left
SetScrollPos(_value - _pageSize);
scrollEvent(SB_PAGELEFT);
} else if (point.x >= thumbRect.right) {
// Right of thumb, page right
SetScrollPos(_value + _pageSize);
scrollEvent(SB_PAGERIGHT);
} else {
// Directly on thumb, so start dragging it
SetScrollPos(getIndexFromX(point.x));
SetCapture();
scrollEvent(SB_THUMBTRACK);
}
}
}
void CScrollBar::OnLButtonUp(unsigned int nFlags, CPoint point) {
if (GetCapture() == m_hWnd) {
ReleaseCapture();
scrollEvent(SB_THUMBPOSITION);
}
scrollEvent(SB_ENDSCROLL);
}
void CScrollBar::OnMouseMove(unsigned int, CPoint point) {
if (GetCapture() == m_hWnd) {
SetScrollPos(getIndexFromX(point.x));
scrollEvent(SB_THUMBTRACK);
}
}
void CScrollBar::scrollEvent(int action) {
m_pParentWnd->SendMessage(WM_HSCROLL,
MAKEWPARAM(action, _value),
(LPARAM)m_hWnd);
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,157 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CSingleDocTemplate, CDocTemplate)
BEGIN_MESSAGE_MAP(CSingleDocTemplate, CDocTemplate)
END_MESSAGE_MAP()
CSingleDocTemplate::~CSingleDocTemplate() {
assert(!m_pOnlyDoc);
}
CDocument *CSingleDocTemplate::OpenDocumentFile(const char *lpszPathName,
bool bMakeVisible) {
CDocument *pDocument = nullptr;
CFrameWnd *pFrame = nullptr;
bool bCreated = false; // => doc and frame created
bool bWasModified = false;
if (m_pOnlyDoc != nullptr) {
// already have a document - reinit it
pDocument = m_pOnlyDoc;
if (!pDocument->SaveModified())
return nullptr; // leave the original one
pFrame = (CFrameWnd *)AfxGetMainWnd();
assert(pFrame != nullptr);
ASSERT_KINDOF(CFrameWnd, pFrame);
ASSERT_VALID(pFrame);
} else {
// create a new document
pDocument = CreateNewDocument();
assert(pFrame == nullptr); // will be created below
bCreated = true;
}
assert(pDocument == m_pOnlyDoc);
if (pFrame == nullptr) {
assert(bCreated);
// Create frame - set as main document frame
bool bAutoDelete = pDocument->m_bAutoDelete;
pDocument->m_bAutoDelete = false;
// don't destroy if something goes wrong
pFrame = CreateNewFrame(pDocument, nullptr);
pDocument->m_bAutoDelete = bAutoDelete;
assert(pFrame);
}
if (lpszPathName == nullptr) {
// Create a new document
SetDefaultTitle(pDocument);
// Avoid creating temporary compound file when starting up invisible
if (!bMakeVisible)
pDocument->m_bEmbedded = true;
if (!pDocument->OnNewDocument()) {
warning("CDocument::OnNewDocument returned false.");
if (bCreated)
pFrame->DestroyWindow(); // Will destroy document
return nullptr;
}
} else {
// open an existing document
bWasModified = pDocument->IsModified();
pDocument->SetModifiedFlag(false); // not dirty for open
if (!pDocument->OnOpenDocument(lpszPathName)) {
warning("CDocument::OnOpenDocument returned false.");
if (bCreated) {
pFrame->DestroyWindow(); // will destroy document
} else if (!pDocument->IsModified()) {
// Original document is untouched
pDocument->SetModifiedFlag(bWasModified);
} else {
// We corrupted the original document
SetDefaultTitle(pDocument);
if (!pDocument->OnNewDocument()) {
warning("Error: OnNewDocument failed after trying to open a document - trying to continue.");
// Assume we can continue
}
}
return nullptr; // Open failed
}
pDocument->SetPathName(lpszPathName);
}
// Set as main frame
CWinApp *app = AfxGetApp();
if (bCreated && !app->m_pMainWnd) {
// Set as main frame (InitialUpdateFrame will show the window)
app->m_pMainWnd = pFrame;
}
InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
return pDocument;
}
void CSingleDocTemplate::AddDocument(CDocument *pDoc) {
ASSERT(m_pOnlyDoc == nullptr); // one at a time please
ASSERT_VALID(pDoc);
CDocTemplate::AddDocument(pDoc);
m_pOnlyDoc = pDoc;
}
void CSingleDocTemplate::SetDefaultTitle(CDocument *pDocument) {
pDocument->SetTitle("Untitled");
}
POSITION CSingleDocTemplate::GetFirstDocPosition() const {
return (m_pOnlyDoc == nullptr) ? nullptr : (POSITION)true;
}
CDocument *CSingleDocTemplate::GetNextDoc(POSITION &rPos) const {
CDocument *pDoc = nullptr;
if (rPos) {
// First time through, return the single document
assert(m_pOnlyDoc != nullptr);
pDoc = m_pOnlyDoc;
}
rPos = nullptr; // No more
return pDoc;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,33 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CStatic, CWnd)
BEGIN_MESSAGE_MAP(CStatic, CWnd)
END_MESSAGE_MAP()
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,40 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxstr.h"
#include "bagel/mfc/global_functions.h"
namespace Bagel {
namespace MFC {
bool CString::LoadString(unsigned int nID) {
char szTemp[256];
int nLen = MFC::LoadString(AfxGetInstanceHandle(), nID, szTemp, sizeof(szTemp));
if (nLen == 0)
return false;
*this = szTemp;
return true;
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,96 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CView, CWnd)
BEGIN_MESSAGE_MAP(CView, CWnd)
ON_WM_PAINT()
ON_WM_NCDESTROY()
END_MESSAGE_MAP()
bool CView::PreCreateWindow(CREATESTRUCT &cs) {
assert(cs.style & WS_CHILD);
return true;
}
int CView::OnCreate(LPCREATESTRUCT lpcs) {
if (CWnd::OnCreate(lpcs) == -1)
return -1;
// If ok, wire in the current document
assert(m_pDocument == nullptr);
CCreateContext *pContext = (CCreateContext *)lpcs->lpCreateParams;
// A view should be created in a given context!
if (pContext != nullptr && pContext->m_pCurrentDoc != nullptr) {
pContext->m_pCurrentDoc->AddView(this);
assert(m_pDocument != nullptr);
} else {
warning("Creating a pane with no CDocument.\n");
}
return 0;
}
void CView::OnDestroy() {
CFrameWnd *pFrame = GetParentFrame();
if (pFrame != nullptr && pFrame->GetActiveView() == this)
pFrame->SetActiveView(nullptr); // deactivate during death
CWnd::OnDestroy();
}
void CView::OnNcDestroy() {
CWnd::OnNcDestroy();
// De-register the view from the document
if (m_pDocument)
m_pDocument->RemoveView(this);
m_pDocument = nullptr;
PostNcDestroy();
}
void CView::PostNcDestroy() {
// Default implementation destroys view
delete this;
}
void CView::OnInitialUpdate() {
OnUpdate(nullptr, 0, nullptr);
}
void CView::OnUpdate(CView *pSender, LPARAM /*lHint*/, CObject * /*pHint*/) {
assert(pSender != this);
Invalidate(true);
}
void CView::OnPaint() {
CPaintDC dc(this);
OnDraw(&dc);
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,490 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/system.h"
#include "common/config-manager.h"
#include "common/events.h"
#include "common/textconsole.h"
#include "graphics/paletteman.h"
#include "bagel/mfc/global_functions.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/win_hand.h"
#include "bagel/mfc/gfx/cursor.h"
#include "bagel/mfc/libs/events.h"
#include "engines/engine.h"
namespace Bagel {
namespace MFC {
/**
* Used for temporary handle wrapper objects
*/
class CTempGdiObject : public CGdiObject {
DECLARE_DYNCREATE(CTempGdiObject)
};
IMPLEMENT_DYNCREATE(CTempGdiObject, CGdiObject)
IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
CWinApp *CWinApp::_activeApp = nullptr;
CWinApp::CWinApp(const char *appName) :
CWinThread(), EventLoop(),
_cursors(_resources),
_fonts(_resources) {
_priorWinApp = _activeApp;
_activeApp = this;
Libs::Event::init();
}
CWinApp::~CWinApp() {
// Free the defaults
_defaultFont.DeleteObject();
_defaultPen.DeleteObject();
_defaultBrush.DeleteObject();
_currentPalette.DeleteObject();
_systemPalette.DeleteObject();
// Release the handle maps
delete m_pmapHDC;
delete m_pmapHGDIOBJ;
m_pmapHDC = nullptr;
m_pmapHGDIOBJ = nullptr;
_activeApp = _priorWinApp;
}
bool CWinApp::InitApplication() {
_settings.load();
_defaultFont.CreateFont(8, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, OUT_RASTER_PRECIS, 0, PROOF_QUALITY, FF_ROMAN, "MS Sans Serif");
_defaultPen.CreatePen(PS_SOLID, 1, 0);
_defaultBrush.CreateSolidBrush(RGB(255, 255, 255));
// Set up current palette. It's empty by default, but
// we need to at least get it registered.
// Then it will be filled out via setPalette later
LOGPALETTE lp;
lp.palVersion = 0x300;
lp.palNumEntries = 0;
_currentPalette.CreatePalette(&lp);
// Set up system palette
LOGPALETTE *lps = (LOGPALETTE *)malloc(sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY));
lps->palVersion = 0x300;
lps->palNumEntries = 256;
Common::fill((byte *)&lps->palPalEntry[0], (byte *)&lps->palPalEntry[Graphics::PALETTE_COUNT], 0);
// Set first 10 system palette colors
PALETTEENTRY sysColorsStart[10] = {
{ 0x00, 0x00, 0x00, 0 }, // 0: Black
{ 0x80, 0x00, 0x00, 0 }, // 1: Dark Red
{ 0x00, 0x80, 0x00, 0 }, // 2: Dark Green
{ 0x80, 0x80, 0x00, 0 }, // 3: Olive
{ 0x00, 0x00, 0x80, 0 }, // 4: Dark Blue
{ 0x80, 0x00, 0x80, 0 }, // 5: Purple
{ 0x00, 0x80, 0x80, 0 }, // 6: Teal
{ 0xC0, 0xC0, 0xC0, 0 }, // 7: Gray
{ 0xC0, 0xDC, 0xC0, 0 }, // 8: Silver (Windows UI color)
{ 0xA6, 0xCA, 0xF0, 0 } // 9: Light Gray (Windows UI color)
};
for (int i = 0; i < 10; ++i) {
lps->palPalEntry[i] = sysColorsStart[i];
}
// Set last 10 system palette colors
PALETTEENTRY sysColorsEnd[10] = {
{ 0xFF, 0xFF, 0xFF, 0 }, // 246: White
{ 0xFF, 0x00, 0x00, 0 }, // 247: Red
{ 0x00, 0xFF, 0x00, 0 }, // 248: Green
{ 0xFF, 0xFF, 0x00, 0 }, // 249: Yellow
{ 0x00, 0x00, 0xFF, 0 }, // 250: Blue
{ 0xFF, 0x00, 0xFF, 0 }, // 251: Magenta
{ 0x00, 0xFF, 0xFF, 0 }, // 252: Cyan
{ 0xFF, 0xFF, 0xFF, 0 }, // 253: White again (duplicate of 246)
{ 0xFF, 0xFB, 0xF0, 0 }, // 254: Light Gray (UI highlight)
{ 0xA0, 0xA0, 0xA4, 0 } // 255: "Button face" gray
};
for (int i = 0; i < 10; ++i) {
lps->palPalEntry[246 + i] = sysColorsEnd[i];
}
// Set up the system palette with the palette data
_systemPalette.CreatePalette(lps);
free(lps);
return true;
}
bool CWinApp::InitInstance() {
return true;
}
int CWinApp::ExitInstance() {
return 0;
}
bool CWinApp::SaveAllModified() {
_settings.save();
return true;
}
int CWinApp::Run() {
if (shouldQuit())
return 0;
// Ensure app has been initialized
assert(_defaultFont.font());
SetCursor(LoadCursor(IDC_ARROW));
if (!m_pMainWnd) {
m_pMainWnd = GetActiveWindow();
assert(m_pMainWnd);
} else {
assert(m_pMainWnd);
SetActiveWindow(m_pMainWnd);
}
runEventLoop(false);
SaveAllModified();
ExitInstance();
return 0;
}
void CWinApp::SetDialogBkColor() {
}
HCURSOR CWinApp::LoadStandardCursor(const char *lpszCursorName) {
return _cursors.loadCursor((intptr)lpszCursorName);
}
HCURSOR CWinApp::LoadCursor(const char *lpszResourceName) {
return _cursors.loadCursor((intptr)lpszResourceName);
}
HCURSOR CWinApp::LoadCursor(unsigned int nIDResource) {
return _cursors.loadCursor(nIDResource);
}
HCURSOR CWinApp::SetCursor(HCURSOR hCursor) {
if (hCursor == _currentCursor)
return hCursor;
HCURSOR oldCursor = _currentCursor;
_currentCursor = hCursor;
Gfx::Cursor *c = (Gfx::Cursor *)hCursor;
if (c) {
c->showCursor();
} else {
Gfx::Cursor::hide();
}
return oldCursor;
}
void CWinApp::BeginWaitCursor() {
DoWaitCursor(1);
}
void CWinApp::EndWaitCursor() {
DoWaitCursor(-1);
}
void CWinApp::DoWaitCursor(int nCode) {
assert(nCode == 0 || nCode == 1 || nCode == -1);
m_nWaitCursorCount += nCode;
if (m_nWaitCursorCount > 0) {
// Set wait cursor
HCURSOR hcurPrev = MFC::SetCursor(_cursors._waitCursor);
if (nCode > 0 && m_nWaitCursorCount == 1)
m_hcurWaitCursorRestore = hcurPrev;
} else {
// Turn off wait cursor
m_nWaitCursorCount = 0;
MFC::SetCursor(m_hcurWaitCursorRestore);
}
}
HFONT CWinApp::getFont(const char *lpszFacename, int nHeight) {
if ((!lpszFacename || !*lpszFacename) || !nHeight)
// Use default font
return _fonts.getFont("MS Sans Serif", 8);
else
return _fonts.getFont(lpszFacename, nHeight);
}
void CWinApp::AddDocTemplate(CDocTemplate *pTemplate) {
if (m_pDocManager == NULL)
m_pDocManager = new CDocManager();
m_pDocManager->AddDocTemplate(pTemplate);
}
void CWinApp::OnFileNew() {
if (m_pDocManager != nullptr)
m_pDocManager->OnFileNew();
}
void CWinApp::OnFileOpen() {
assert(m_pDocManager != nullptr);
m_pDocManager->OnFileOpen();
}
void CWinApp::CloseAllDocuments(bool bEndSession) {
if (m_pDocManager != nullptr)
m_pDocManager->CloseAllDocuments(bEndSession);
}
unsigned int CWinApp::GetProfileInt(const char *lpszSection,
const char *lpszEntry, int nDefault) {
return _settings[lpszSection].getInt(lpszEntry, nDefault);
}
void CWinApp::WriteProfileInt(const char *lpszSection,
const char *lpszEntry, int nValue) {
_settings[lpszSection].setInt(lpszEntry, nValue);
}
CString CWinApp::GetProfileString(const char *lpszSection,
const char *lpszEntry, const char *lpszDefault) {
Common::String str = _settings[lpszSection].getString(lpszEntry, lpszDefault);
return CString(str.c_str());
}
bool CWinApp::WriteProfileString(const char *lpszSection,
const char *lpszEntry, const char *lpszValue) {
_settings[lpszSection].setString(lpszEntry, lpszValue);
return true;
}
void CWinApp::setDirectory(const char *folder) {
const Common::FSNode gameDataDir(ConfMan.getPath("path"));
SearchMan.remove("CurrentDir");
_currentDirectory = gameDataDir;
if (folder && *folder) {
_currentDirectory = gameDataDir.getChild(folder);
SearchMan.addDirectory("CurrentDir", _currentDirectory, 10, 2);
}
}
void CWinApp::setPalette(const Graphics::Palette &pal) {
_currentPalette.SetPaletteEntries(pal);
g_system->getPaletteManager()->setPalette(pal);
}
byte CWinApp::getColor(COLORREF color) const {
if (_currentPalette.isEmpty())
return 0;
if (color <= 0xff || (color >> 24) == 1)
return (byte)(color & 0xff);
return _currentPalette.palette()->findBestColor(
GetRValue(color),
GetGValue(color),
GetBValue(color)
);
}
HRSRC CWinApp::findResource(const char *lpName, const char *lpType) {
return _resources.findResource(lpName, lpType);
}
size_t CWinApp::sizeofResource(HRSRC hResInfo) {
return _resources.resourceSize(hResInfo);
}
HGLOBAL CWinApp::loadResource(HRSRC hResInfo) {
return _resources.loadResource(hResInfo);
}
void *CWinApp::lockResource(HGLOBAL hResData) {
return GlobalLock(hResData);
}
void CWinApp::unlockResource(HGLOBAL hResData) {
GlobalUnlock(hResData);
}
bool CWinApp::freeResource(HGLOBAL hResData) {
GlobalFree(hResData);
return true;
}
CHandleMap<CGdiObject> *CWinApp::afxMapHGDIOBJ(bool bCreate) {
if (m_pmapHGDIOBJ == nullptr && bCreate)
m_pmapHGDIOBJ = new CHandleMap<CGdiObject>();
return m_pmapHGDIOBJ;
}
CHandleMap<CDC> *CWinApp::afxMapHDC(bool bCreate) {
if (m_pmapHDC == nullptr && bCreate)
m_pmapHDC = new CHandleMap<CDC>();
return m_pmapHDC;
}
CHandleMap<CWnd> *CWinApp::afxMapWnd(bool bCreate) {
if (m_pmapWnd == nullptr && bCreate)
m_pmapWnd = new CHandleMap<CWnd>();
return m_pmapWnd;
}
void CWinApp::AfxUnlockTempMaps() {
if (m_pmapHDC)
m_pmapHDC->DeleteTemp();
if (m_pmapHGDIOBJ)
m_pmapHGDIOBJ->DeleteTemp();
}
const char *CWinApp::AfxRegisterWndClass(unsigned int nClassStyle,
HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon) {
return "ScummVMWindow";
}
bool CWinApp::GetClassInfo(HINSTANCE hInstance,
const char *lpClassName, LPWNDCLASS lpWndClass) {
assert(lpWndClass);
WNDCLASS &wc = *lpWndClass;
memset(lpWndClass, 0, sizeof(WNDCLASS));
wc.style = CS_DBLCLKS | CS_BYTEALIGNWINDOW | CS_OWNDC;
return true;
}
/*--------------------------------------------*/
CWinApp *AfxGetApp() {
return CWinApp::_activeApp;
}
CWnd *AfxGetMainWnd() {
assert(CWinApp::_activeApp);
return CWinApp::_activeApp->m_pMainWnd;
}
HINSTANCE AfxGetInstanceHandle() {
// Unused in ScummVM
return 0;
}
int LoadString(HINSTANCE hInstance, unsigned int uID,
char *lpBuffer, int cchBufferMax) {
if (lpBuffer == nullptr || cchBufferMax <= 0)
return 0;
// Calculate which string block (resource ID) contains this string
unsigned int blockID = (uID / 16) + 1;
unsigned int indexInBlock = uID % 16;
// Find the RT_STRING resource with that block ID
HRSRC hRes = FindResource(hInstance, MAKEINTRESOURCE(blockID), RT_STRING);
if (!hRes)
return 0;
HGLOBAL hResData = LoadResource(hInstance, hRes);
if (!hResData)
return 0;
const byte *pData = (const byte *)LockResource(hResData);
assert(pData);
// Walk through up to 16 strings in the block
for (uint i = 0; i < 16; ++i) {
uint length = *pData++;
if (i == indexInBlock) {
// Found the desired string
int copyLen = MIN((int)length, cchBufferMax - 1);
memcpy(lpBuffer, (const char *)pData, copyLen);
lpBuffer[copyLen] = '\0';
UnlockResource(hResData);
FreeResource(hResData);
return copyLen;
}
// Skip this string
pData += length;
}
// String ID not found (shouldn't happen if resource is valid)
UnlockResource(hResData);
FreeResource(hResData);
return 0;
}
HMODULE LoadLibrary(const char *lpLibFileName) {
error("LoadLibrary is unsupported");
}
void FreeLibrary(HMODULE hModule) {
error("FreeLibrary is unsupported");
}
FARPROC GetProcAddress(HMODULE hModule,
const char *lpProcName) {
error("TODO: GetProcAddress");
}
HMODULE GetModuleHandle(const char *lpModuleName) {
error("TODO: GetModuleHandle");
}
const char *AfxRegisterWndClass(unsigned int nClassStyle,
HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon) {
return AfxGetApp()->AfxRegisterWndClass(nClassStyle,
hCursor, hbrBackground, hIcon);
}
bool GetClassInfo(HINSTANCE hInstance,
const char *lpClassName, LPWNDCLASS lpWndClass) {
return AfxGetApp()->GetClassInfo(hInstance, lpClassName, lpWndClass);
}
int GetSystemMetrics(int nIndex) {
switch (nIndex) {
case SM_CXCURSOR:
return Gfx::CURSOR_W;
case SM_CYCURSOR:
return Gfx::CURSOR_H;
case SM_CXSCREEN:
return g_system->getWidth();
case SM_CYSCREEN:
return g_system->getHeight();
default:
error("TODO: GetSystemMetrics");
break;
}
}
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,146 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_WIN_HAND_H
#define BAGEL_MFC_WIN_HAND_H
#include "common/hashmap.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
class CGdiObject;
class CDC;
struct VoidPtr_EqualTo {
bool operator()(const void *x, const void *y) const {
return x == y;
}
};
struct VoidPtr_Hash {
uint operator()(const void *x) const {
return (intptr)x;
}
};
template<typename T>
struct HandleTraits;
// Specialize for CGdiObject
template<>
struct HandleTraits<CGdiObject> {
static HANDLE &GetHandle(CGdiObject &obj) {
return *(HANDLE *)&obj.m_hObject;
}
};
// Specialize for CDC
template<>
struct HandleTraits<CDC> {
static HANDLE &GetHandle(CDC &obj) {
return *(HANDLE *)&obj.m_hDC;
}
};
template<class T>
class CHandleMap {
public:
typedef Common::HashMap<void *, T *,
VoidPtr_Hash, VoidPtr_EqualTo> CMapPtrToPtr;
private:
CMapPtrToPtr _permanentMap;
CMapPtrToPtr _temporaryMap;
public:
~CHandleMap() {
DeleteTemp();
}
T *FromHandle(HANDLE h) {
if (h == nullptr)
return nullptr;
// Check for permanent object, and return if present
T *pObject = LookupPermanent(h);
if (pObject != nullptr)
return pObject;
else if ((pObject = LookupTemporary(h)) != nullptr) {
assert(HandleTraits<T>::GetHandle(*pObject) == h ||
HandleTraits<T>::GetHandle(*pObject) == nullptr);
HandleTraits<T>::GetHandle(*pObject) = h;
return pObject;
}
// This wasn't created by us, so create a temporary one.
T *pTemp = (T *)T::CreateObject();
assert(pTemp);
_temporaryMap[h] = pTemp;
// Now set the handle in the object and return it
HandleTraits<T>::GetHandle(*pTemp) = h;
return pTemp;
}
void DeleteTemp() {
for (auto &entry : _temporaryMap) {
HANDLE h = entry._key;
T *pTemp = entry._value;
// Zero out the handle
assert(HandleTraits<T>::GetHandle(*pTemp) == h ||
HandleTraits<T>::GetHandle(*pTemp) == nullptr);
HandleTraits<T>::GetHandle(*pTemp) = nullptr;
delete pTemp;
}
_temporaryMap.clear();
}
void SetPermanent(HANDLE h, T *permOb) {
assert(!LookupPermanent(h));
_permanentMap[(void *)h] = permOb;
}
void RemoveHandle(HANDLE h) {
_permanentMap.erase((void *)h);
}
inline T *LookupPermanent(HANDLE h) const {
return _permanentMap.contains((void *)h) ?
_permanentMap[(void *)h] : nullptr;
}
inline T *LookupTemporary(HANDLE h) const {
return _temporaryMap.contains((void *)h) ?
_temporaryMap[(void *)h] : nullptr;
}
};
} // namespace MFC
} // namespace Bagel
#endif

View File

@@ -0,0 +1,31 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "bagel/mfc/afxwin.h"
namespace Bagel {
namespace MFC {
IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget)
} // namespace MFC
} // namespace Bagel

View File

@@ -0,0 +1,460 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/system.h"
#include "common/textconsole.h"
#include "bagel/mfc/wingdi.h"
#include "bagel/mfc/global_functions.h"
#include "bagel/mfc/afxwin.h"
#include "bagel/mfc/gfx/blitter.h"
#include "bagel/mfc/gfx/palette_map.h"
namespace Bagel {
namespace MFC {
int GetDeviceCaps(HDC hdc, int index) {
CDC::Impl *dc = (CDC::Impl *)hdc;
const CBitmap::Impl *bitmap = (CBitmap::Impl *)dc->_bitmap;
switch (index) {
case HORZRES:
return bitmap->w;
case VERTRES:
return bitmap->h;
case BITSPIXEL:
return bitmap->format.bytesPerPixel * 8;
case RASTERCAPS:
return (bitmap->format.bytesPerPixel == 1 ? RC_PALETTE : 0) |
RC_BITBLT |
RC_BITMAP64 |
RC_DI_BITMAP |
RC_DIBTODEV |
RC_STRETCHBLT;
default:
break;
}
error("TODO: CDC::GetDeviceCaps");
return 0;
}
HDC CreateCompatibleDC(HDC hdc) {
return new CDC::Impl(hdc);
}
HDC GetDC(HWND hWnd) {
if (hWnd) {
CWnd *wnd = CWnd::FromHandle(hWnd);
CDC *dc = wnd->GetDC();
return dc->m_hDC;
} else {
// Screen DC, so set the screen rect
CDC::Impl *dc = new CDC::Impl();
dc->setScreenRect();
return dc;
}
}
int ReleaseDC(HWND hWnd, HDC hDC) {
if (hWnd) {
// Window based DC
CWnd *wnd = CWnd::FromHandle(hWnd);
CDC *dc = CDC::FromHandle(hDC);
return wnd->ReleaseDC(dc);
} else {
// System screen DC
delete (CDC::Impl *)hDC;
return 1;
}
}
bool DeleteDC(HDC hDC) {
delete (CDC::Impl *)hDC;
return true;
}
bool DeleteObject(HGDIOBJ ho) {
delete (CGdiObjectImpl *)ho;
return true;
}
int GetObject(HANDLE h, int c, void *pv) {
error("TODO: GetObject");
}
HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint) {
CWnd *wnd = static_cast<CWnd *>(hWnd);
return wnd->BeginPaint(lpPaint);
}
bool EndPaint(HWND hWnd, const PAINTSTRUCT *lpPaint) {
CWnd *wnd = static_cast<CWnd *>(hWnd);
return wnd->EndPaint(lpPaint);
}
intptr DialogBoxParam(HINSTANCE hInstance,
const char *lpTemplateName, HWND hWndParent,
DLGPROC lpDialogFunc, LPARAM dwInitParam) {
error("TODO: DialogBoxParam");
}
bool IsWindow(HWND hWnd) {
error("TODO: IsWindow");
}
bool SetWindowText(HWND hWnd, const char *lpszString) {
CWnd *wnd = CWnd::FromHandle(hWnd);
wnd->SetWindowText(lpszString);
return true;
}
int GetWindowText(HWND hWnd, char *lpszStringBuf, int nMaxCount) {
CWnd *wnd = CWnd::FromHandle(hWnd);
return wnd->GetWindowText(lpszStringBuf, nMaxCount);
}
bool ScreenToClient(HWND hWnd, LPPOINT lpPoint) {
CWnd *wnd = CWnd::FromHandle(hWnd);
wnd->ScreenToClient(lpPoint);
return true;
}
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h) {
CDC::Impl *dc = (CDC::Impl *)hdc;
return dc->Attach(h);
}
HGDIOBJ GetStockObject(int i) {
switch (i) {
case SYSTEM_FONT:
return AfxGetApp()->getDefaultFont();
default:
break;
}
error("TODO: GetStockObject value");
}
HPALETTE SelectPalette(HDC hdc, HPALETTE hPal, bool bForceBkgd) {
auto *surf = static_cast<CDC::Impl *>(hdc);
return surf->selectPalette(hPal, bForceBkgd);
}
unsigned int RealizePalette(HDC hdc) {
auto *surf = static_cast<CDC::Impl *>(hdc);
surf->realizePalette();
return 256;
}
HBITMAP CreateDIBitmap(HDC hdc, CONST BITMAPINFOHEADER *pbmih, uint32 flInit,
CONST void *pjBits, CONST BITMAPINFO *pbmi, unsigned int iUsage) {
CBitmap::Impl *bitmap = new CBitmap::Impl();
// Figure out the pixel format
assert(pbmih->biSize == 40 && pbmih->biPlanes == 1);
Graphics::PixelFormat format;
switch (pbmih->biBitCount) {
case 1:
// Monochrome. Since ScummVM doesn't support it directly,
// I use a standard 8bpp surface, but in the format's
// aLoss field, I use a value of 255 as a flag.
// This should be okay, as loss & shift aren't used for 8bpp.
format = Graphics::PixelFormat::createFormatCLUT8();
format.aLoss = 255;
break;
case 8:
format = Graphics::PixelFormat::createFormatCLUT8();
break;
case 16:
format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
break;
case 32:
format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
break;
default:
error("Unknown biBitCount");
break;
}
// Create the bitmap
bitmap->create(pbmih->biWidth, pbmih->biHeight, format);
// Set the palette
Graphics::Palette pal((pbmi && pbmih->biClrUsed) ? pbmih->biClrUsed : 0);
if (pbmi && pbmih->biClrUsed) {
for (uint i = 0; i < pbmih->biClrUsed; ++i) {
const RGBQUAD &col = pbmi->bmiColors[i];
pal.set(i, col.rgbRed, col.rgbGreen, col.rgbBlue);
}
// bitmap->setPalette(pal.data(), 0, pal.size());
}
// If pixels are provided, copy them over
if (flInit & CBM_INIT) {
assert(pjBits);
if (bitmap->format.bytesPerPixel == 1 && !pal.empty()) {
const CDC::Impl *destDC = (const CDC::Impl *)hdc;
const CPalette::Impl *destPal = (const CPalette::Impl * )destDC->_palette;
Gfx::PaletteMap palMap(pal, *destPal);
palMap.map((const byte *)pjBits, (byte *)bitmap->getPixels(),
bitmap->w * bitmap->h);
} else {
size_t size = bitmap->w * bitmap->h *
bitmap->format.bytesPerPixel;
Common::copy((const byte *)pjBits, (const byte *)pjBits + size,
(byte *)bitmap->getPixels());
}
}
return bitmap;
}
int GetDIBits(HDC hdc, HBITMAP hbm, unsigned int start, unsigned int cLines,
void *lpvBits, LPBITMAPINFO lpbmi, unsigned int usage) {
error("TODO: GetDIBits");
}
bool BitBlt(HDC hdc, int xDest, int yDest, int width, int height,
HDC hdcSrc, int xSrc, int ySrc, uint32 rop) {
CDC::Impl *srcDc = (CDC::Impl *)hdcSrc;
CDC::Impl *destDc = (CDC::Impl *)hdc;
CBitmap::Impl *src = (CBitmap::Impl *)srcDc->_bitmap;
CBitmap::Impl *dest = (CBitmap::Impl *)destDc->_bitmap;
uint bgColor = destDc->getBkColor();
Gfx::blit(src, dest,
Common::Rect(xSrc, ySrc, xSrc + width, ySrc + height),
Common::Point(xDest, yDest),
bgColor, rop, nullptr);
return true;
}
bool StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest,
HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, uint32 rop) {
CDC *srcDC = CDC::FromHandle(hdcSrc);
CDC *destDC = CDC::FromHandle(hdcDest);
return destDC->StretchBlt(xDest, yDest, wDest, hDest,
srcDC, xSrc, ySrc, wSrc, hSrc, rop);
}
int SetStretchBltMode(HDC hdc, int mode) {
CDC *dc = CDC::FromHandle(hdc);
return dc->SetStretchBltMode(mode);
}
int StretchDIBits(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight,
int xSrc, int ySrc, int SrcWidth, int SrcHeight,
CONST void *lpBits, CONST BITMAPINFO *lpbmi, unsigned int iUsage, uint32 rop) {
error("TODO: StretchDIBits");
}
int GetTextExtent(HDC hdc, const char *text, size_t len) {
CDC *dc = CDC::FromHandle(hdc);
CSize size = dc->GetTextExtent(CString(text, len));
return size.cx;
}
bool GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm) {
CDC *dc = CDC::FromHandle(hdc);
return dc->GetTextMetrics(lptm);
}
intptr GetWindowWord(HWND hWnd, int nIndex) {
assert(nIndex == GWW_HINSTANCE);
return 0;
}
int AddFontResource(const char *fontName) {
return AfxGetApp()->addFontResource(fontName);
}
bool RemoveFontResource(const char *fontName) {
return AfxGetApp()->removeFontResource(fontName);
}
int SetScrollPos(HWND hWnd, int /*nBar*/,
int nPos, bool bRedraw) {
CWnd *wnd = CWnd::FromHandle(hWnd);
return wnd->SetScrollPos(nPos, bRedraw);
}
void SetScrollRange(HWND hWnd, int /*nBar*/,
int nMinPos, int nMaxPos, bool bRedraw) {
CWnd *wnd = CWnd::FromHandle(hWnd);
wnd->SetScrollRange(nMinPos, nMaxPos, bRedraw);
}
bool ClipCursor(const RECT *lpRect) {
// Ignored in ScummVM
return false;
}
bool GetCursorPos(LPPOINT lpPoint) {
Common::Point mousePos = AfxGetApp()->getMousePos();
lpPoint->x = mousePos.x;
lpPoint->y = mousePos.y;
return true;
}
bool SetCursorPos(int x, int y) {
AfxGetApp()->setMousePos(Common::Point(x, y));
return true;
}
bool SetCapture(HWND hWnd) {
AfxGetApp()->SetCapture(hWnd);
return true;
}
bool ReleaseCapture() {
AfxGetApp()->ReleaseCapture();
return true;
}
HWND GetCapture() {
return AfxGetApp()->GetCapture();
}
HCURSOR LoadCursor(HINSTANCE hInstance,
const char *lpCursorName) {
return AfxGetApp()->LoadCursor(lpCursorName);
}
HCURSOR SetCursor(HCURSOR hCursor) {
return AfxGetApp()->SetCursor(hCursor);
}
int ShowCursor(bool bShow) {
g_system->showMouse(bShow);
return 0;
}
bool LineDDA(int x0, int y0, int x1, int y1, LINEDDAPROC lpProc, CDC *cdc) {
if (!lpProc)
return false;
int dx = ABS(x1 - x0);
int dy = ABS(y1 - y0);
int sx = (x0 < x1) ? 1 : -1;
int sy = (y0 < y1) ? 1 : -1;
int err = dx - dy;
for (;;) {
lpProc(x0, y0, cdc); // Call the callback for this pixel
if (x0 == x1 && y0 == y1)
break;
int e2 = 2 * err;
if (e2 > -dy)
{
err -= dy;
x0 += sx;
}
if (e2 < dx)
{
err += dx;
y0 += sy;
}
}
return true;
}
byte GetRValue(COLORREF color) {
return ((byte)(color & 0xFF));
}
byte GetGValue(COLORREF color) {
return ((byte)((color >> 8) & 0xFF));
}
byte GetBValue(COLORREF color) {
return ((byte)((color >> 16) & 0xFF));
}
HWND GetDlgItem(HWND hDlg, int nIDDlgItem) {
error("TODO: GetDlgItem");
}
bool EndDialog(HWND hDlg, intptr nResult) {
error("TODO: EndDialog");
}
bool SetDlgItemInt(HWND hDlg, int nIDDlgItem,
unsigned int uValue, bool bSigned) {
error("TODO: SetDlgItemInt");
}
bool CheckRadioButton(HWND hDlg, int nIDFirstButton,
int nIDLastButton, int nIDCheckButton) {
error("TODO: CheckRadioButton");
}
uint32 GetSysColor(int nIndex) {
switch (nIndex) {
case COLOR_3DHIGHLIGHT:
return RGB(255, 255, 255);
case COLOR_BTNSHADOW:
return RGB(128, 128, 128);
case COLOR_BTNFACE:
return RGB(192, 192, 192);
case COLOR_BTNTEXT:
case COLOR_WINDOWTEXT:
return RGB(0, 0, 0);
default:
error("Unknown GetSysColor value");
break;
}
}
HBRUSH GetSysColorBrush(int nIndex) {
switch (nIndex) {
case COLOR_WINDOW:
return new CBrush::Impl(RGB(255, 255, 255));
default:
error("Unknown GetSysColorBrush value");
break;
}
}
bool DestroyMenu(HMENU hMenu) {
error("TODO: DestroyMenu");
}
void SetActiveWindow(HWND hWnd) {
error("TODO: SetActiveWindow");
}
} // namespace MFC
} // namespace Bagel

812
engines/bagel/mfc/wingdi.h Normal file
View File

@@ -0,0 +1,812 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_WINGDI_H
#define BAGEL_MFC_WINGDI_H
#include "bagel/mfc/minwindef.h"
namespace Bagel {
namespace MFC {
class CDC;
#define PALETTEINDEX(i) ((COLORREF)(0x01000000 | (uint32)(uint16)(i)))
/*
* Class styles
*/
#define CS_VREDRAW 0x0001
#define CS_HREDRAW 0x0002
#define CS_DBLCLKS 0x0008
#define CS_OWNDC 0x0020
#define CS_CLASSDC 0x0040
#define CS_PARENTDC 0x0080
#define CS_NOCLOSE 0x0200
#define CS_SAVEBITS 0x0800
#define CS_BYTEALIGNCLIENT 0x1000
#define CS_BYTEALIGNWINDOW 0x2000
#define CS_GLOBALCLASS 0x4000
/* Device Parameters for GetDeviceCaps() */
#define DRIVERVERSION 0 /* Device driver version */
#define TECHNOLOGY 2 /* Device classification */
#define HORZSIZE 4 /* Horizontal size in millimeters */
#define VERTSIZE 6 /* Vertical size in millimeters */
#define HORZRES 8 /* Horizontal width in pixels */
#define VERTRES 10 /* Vertical height in pixels */
#define BITSPIXEL 12 /* Number of bits per pixel */
#define PLANES 14 /* Number of planes */
#define NUMBRUSHES 16 /* Number of brushes the device has */
#define NUMPENS 18 /* Number of pens the device has */
#define NUMMARKERS 20 /* Number of markers the device has */
#define NUMFONTS 22 /* Number of fonts the device has */
#define NUMCOLORS 24 /* Number of colors the device supports */
#define PDEVICESIZE 26 /* Size required for device descriptor */
#define CURVECAPS 28 /* Curve capabilities */
#define LINECAPS 30 /* Line capabilities */
#define POLYGONALCAPS 32 /* Polygonal capabilities */
#define TEXTCAPS 34 /* Text capabilities */
#define CLIPCAPS 36 /* Clipping capabilities */
#define RASTERCAPS 38 /* Bitblt capabilities */
#define ASPECTX 40 /* Length of the X leg */
#define ASPECTY 42 /* Length of the Y leg */
#define ASPECTXY 44 /* Length of the hypotenuse */
#define LOGPIXELSX 88 /* Logical pixels/inch in X */
#define LOGPIXELSY 90 /* Logical pixels/inch in Y */
#define SIZEPALETTE 104 /* Number of entries in physical palette */
#define NUMRESERVED 106 /* Number of reserved entries in palette */
#define COLORRES 108 /* Actual color resolution */
// Printing related DeviceCaps. These replace the appropriate Escapes
#define PHYSICALWIDTH 110 /* Physical Width in device units */
#define PHYSICALHEIGHT 111 /* Physical Height in device units */
#define PHYSICALOFFSETX 112 /* Physical Printable Area x margin */
#define PHYSICALOFFSETY 113 /* Physical Printable Area y margin */
#define SCALINGFACTORX 114 /* Scaling factor x */
#define SCALINGFACTORY 115 /* Scaling factor y */
// Display driver specific
#define VREFRESH 116 /* Current vertical refresh rate of the */
/* display device (for displays only) in Hz*/
#define DESKTOPVERTRES 117 /* Horizontal width of entire desktop in */
/* pixels */
#define DESKTOPHORZRES 118 /* Vertical height of entire desktop in */
/* pixels */
#define BLTALIGNMENT 119 /* Preferred blt alignment */
#define SHADEBLENDCAPS 120 /* Shading and blending caps */
#define COLORMGMTCAPS 121 /* Color Management caps */
/* Raster Capabilities */
#define RC_NONE
#define RC_BITBLT 1 /* Can do standard BLT. */
#define RC_BANDING 2 /* Device requires banding support */
#define RC_SCALING 4 /* Device requires scaling support */
#define RC_BITMAP64 8 /* Device can support >64K bitmap */
#define RC_GDI20_OUTPUT 0x0010 /* has 2.0 output calls */
#define RC_GDI20_STATE 0x0020
#define RC_SAVEBITMAP 0x0040
#define RC_DI_BITMAP 0x0080 /* supports DIB to memory */
#define RC_PALETTE 0x0100 /* supports a palette */
#define RC_DIBTODEV 0x0200 /* supports DIBitsToDevice */
#define RC_BIGFONT 0x0400 /* supports >64K fonts */
#define RC_STRETCHBLT 0x0800 /* supports StretchBlt */
#define RC_FLOODFILL 0x1000 /* supports FloodFill */
#define RC_STRETCHDIB 0x2000 /* supports StretchDIBits */
#define RC_OP_DX_OUTPUT 0x4000
#define RC_DEVBITS 0x8000
/* Ternary raster operations */
#define SRCCOPY (uint32)0x00CC0020 /* dest = source */
#define SRCPAINT (uint32)0x00EE0086 /* dest = source OR dest */
#define SRCAND (uint32)0x008800C6 /* dest = source AND dest */
#define SRCINVERT (uint32)0x00660046 /* dest = source XOR dest */
#define SRCERASE (uint32)0x00440328 /* dest = source AND (NOT dest ) */
#define NOTSRCCOPY (uint32)0x00330008 /* dest = (NOT source) */
#define NOTSRCERASE (uint32)0x001100A6 /* dest = (NOT src) AND (NOT dest) */
#define MERGECOPY (uint32)0x00C000CA /* dest = (source AND pattern) */
#define MERGEPAINT (uint32)0x00BB0226 /* dest = (NOT source) OR dest */
#define PATCOPY (uint32)0x00F00021 /* dest = pattern */
#define PATPAINT (uint32)0x00FB0A09 /* dest = DPSnoo */
#define PATINVERT (uint32)0x005A0049 /* dest = pattern XOR dest */
#define DSTINVERT (uint32)0x00550009 /* dest = (NOT dest) */
#define BLACKNESS (uint32)0x00000042 /* dest = BLACK */
#define WHITENESS (uint32)0x00FF0062 /* dest = WHITE */
#define NOMIRRORBITMAP (uint32)0x80000000 /* Do not Mirror the bitmap in this call */
#define CAPTUREBLT (uint32)0x40000000 /* Include layered windows */
/* StretchBlt() Modes */
#define BLACKONWHITE 1
#define WHITEONBLACK 2
#define COLORONCOLOR 3
#define HALFTONE 4
#define MAXSTRETCHBLTMODE 4
/* DIB color table identifiers */
#define DIB_RGB_COLORS 0 /* color table in RGBs */
#define DIB_PAL_COLORS 1 /* color table in palette indices */
/* constants for CreateDIBitmap */
#define CBM_INIT 0x04L /* initialize bitmap */
/*
* ShowWindow() Commands
*/
#define SW_HIDE 0
#define SW_SHOWNORMAL 1
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4
#define SW_SHOW 5
#define SW_MINIMIZE 6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA 8
#define SW_RESTORE 9
#define SW_SHOWDEFAULT 10
#define SW_FORCEMINIMIZE 11
#define SW_MAX 11
/* GetWindowWord */
#define GWW_HINSTANCE (-6)
/* Font Families */
#define FF_DONTCARE (0<<4) /* Don't care or don't know. */
#define FF_ROMAN (1<<4) /* Variable stroke width, serifed. */
/* Times Roman, Century Schoolbook, etc. */
#define FF_SWISS (2<<4) /* Variable stroke width, sans-serifed. */
/* Helvetica, Swiss, etc. */
#define FF_MODERN (3<<4) /* Constant stroke width, serifed or sans-serifed. */
/* Pica, Elite, Courier, etc. */
#define FF_SCRIPT (4<<4) /* Cursive, etc. */
#define FF_DECORATIVE (5<<4) /* Old English, etc. */
/* Font Weights */
enum FontWeight {
FW_DONTCARE = 0,
FW_THIN = 100,
FW_EXTRALIGHT = 200,
FW_LIGHT = 300,
FW_NORMAL = 400,
FW_MEDIUM = 500,
FW_SEMIBOLD = 600,
FW_BOLD = 700,
FW_EXTRABOLD = 800,
FW_HEAVY = 900,
FW_ULTRALIGHT = FW_EXTRALIGHT,
FW_REGULAR = FW_NORMAL,
FW_DEMIBOLD = FW_SEMIBOLD,
FW_ULTRABOLD = FW_EXTRABOLD,
FW_BLACK = FW_HEAVY
};
#define OUT_DEFAULT_PRECIS 0
#define OUT_STRING_PRECIS 1
#define OUT_CHARACTER_PRECIS 2
#define OUT_STROKE_PRECIS 3
#define OUT_TT_PRECIS 4
#define OUT_DEVICE_PRECIS 5
#define OUT_RASTER_PRECIS 6
#define OUT_TT_ONLY_PRECIS 7
#define OUT_OUTLINE_PRECIS 8
#define OUT_SCREEN_OUTLINE_PRECIS 9
#define OUT_PS_ONLY_PRECIS 10
#define DEFAULT_QUALITY 0
#define DRAFT_QUALITY 1
#define PROOF_QUALITY 2
#define NONANTIALIASED_QUALITY 3
#define ANTIALIASED_QUALITY 4
/* Background Modes */
#define TRANSPARENT 1
#define OPAQUE 2
#define BKMODE_LAST 2
/*
* Button Control Styles
*/
#define BS_PUSHBUTTON 0x00000000L
#define BS_DEFPUSHBUTTON 0x00000001L
#define BS_CHECKBOX 0x00000002L
#define BS_AUTOCHECKBOX 0x00000003L
#define BS_RADIOBUTTON 0x00000004L
#define BS_3STATE 0x00000005L
#define BS_AUTO3STATE 0x00000006L
#define BS_GROUPBOX 0x00000007L
#define BS_USERBUTTON 0x00000008L
#define BS_AUTORADIOBUTTON 0x00000009L
#define BS_PUSHBOX 0x0000000AL
#define BS_OWNERDRAW 0x0000000BL
#define BS_TYPEMASK 0x0000000FL
#define BS_LEFTTEXT 0x00000020L
#define BS_TEXT 0x00000000L
#define BS_ICON 0x00000040L
#define BS_BITMAP 0x00000080L
#define BS_LEFT 0x00000100L
#define BS_RIGHT 0x00000200L
#define BS_CENTER 0x00000300L
#define BS_TOP 0x00000400L
#define BS_BOTTOM 0x00000800L
#define BS_VCENTER 0x00000C00L
#define BS_PUSHLIKE 0x00001000L
#define BS_MULTILINE 0x00002000L
#define BS_NOTIFY 0x00004000L
#define BS_FLAT 0x00008000L
#define BS_RIGHTBUTTON BS_LEFTTEXT
/*
* Standard Cursor IDs
*/
#define MAKEINTRESOURCE(i) ((char *)((uintptr)((uint16)(i))))
#define IDC_NONE 0
#define IDC_ARROW MAKEINTRESOURCE(32512)
#define IDC_IBEAM MAKEINTRESOURCE(32513)
#define IDC_WAIT MAKEINTRESOURCE(32514)
#define IDC_CROSS MAKEINTRESOURCE(32515)
#define IDC_UPARROW MAKEINTRESOURCE(32516)
#define IDC_SIZE MAKEINTRESOURCE(32640) /* OBSOLETE: use IDC_SIZEALL */
#define IDC_ICON MAKEINTRESOURCE(32641) /* OBSOLETE: use IDC_ARROW */
#define IDC_SIZENWSE MAKEINTRESOURCE(32642)
#define IDC_SIZENESW MAKEINTRESOURCE(32643)
#define IDC_SIZEWE MAKEINTRESOURCE(32644)
#define IDC_SIZENS MAKEINTRESOURCE(32645)
#define IDC_SIZEALL MAKEINTRESOURCE(32646)
#define IDC_NO MAKEINTRESOURCE(32648) /*not in win3.1 */
#define IDC_HAND MAKEINTRESOURCE(32649)
#define IDC_APPSTARTING MAKEINTRESOURCE(32650) /*not in win3.1 */
#define IDC_HELP MAKEINTRESOURCE(32651)
/*
* Owner draw state
*/
enum {
ODS_SELECTED = 0x0001,
ODS_ENABLED = 0x0002,
ODS_DISABLED = 0x0004,
ODS_GRAYED = ODS_DISABLED,
ODS_CHECKED = 0x0008,
ODS_FOCUS = 0x0010,
ODS_DEFAULT = 0x0020,
ODS_COMBOBOXEDIT = 0x1000,
ODS_HOTLIGHT = 0x0040,
ODS_INACTIVE = 0x0080,
ODS_NOACCEL = 0x0100,
ODS_NOFOCUSRECT = 0x0200
};
enum {
BST_UNCHECKED = 0,
BST_CHECKED = 1,
BST_INDETERMINATE = 2,
BST_PUSHED = 4,
BST_FOCUS = 8
};
/* Stock Logical Objects */
#define WHITE_BRUSH 0
#define LTGRAY_BRUSH 1
#define GRAY_BRUSH 2
#define DKGRAY_BRUSH 3
#define BLACK_BRUSH 4
#define NULL_BRUSH 5
#define HOLLOW_BRUSH NULL_BRUSH
#define WHITE_PEN 6
#define BLACK_PEN 7
#define NULL_PEN 8
#define OEM_FIXED_FONT 10
#define ANSI_FIXED_FONT 11
#define ANSI_VAR_FONT 12
#define SYSTEM_FONT 13
#define DEVICE_DEFAULT_FONT 14
#define DEFAULT_PALETTE 15
#define SYSTEM_FIXED_FONT 16
/* Pen Styles */
#define PS_SOLID 0
#define PS_DASH 1 /* ------- */
#define PS_DOT 2 /* ....... */
#define PS_DASHDOT 3 /* _._._._ */
#define PS_DASHDOTDOT 4 /* _.._.._ */
#define PS_NULL 5
#define PS_INSIDEFRAME 6
#define PS_USERSTYLE 7
#define PS_ALTERNATE 8
#define PS_STYLE_MASK 0x0000000F
/*
* Button Control Messages
*/
#define BM_GETCHECK 0x00F0
#define BM_SETCHECK 0x00F1
#define BM_GETSTATE 0x00F2
#define BM_SETSTATE 0x00F3
#define BM_SETSTYLE 0x00F4
#define BM_CLICK 0x00F5
#define BM_GETIMAGE 0x00F6
#define BM_SETIMAGE 0x00F7
#define BM_SETDONTCLICK 0x00F8
/*
* Owner draw control types
*/
#define ODT_MENU 1
#define ODT_LISTBOX 2
#define ODT_COMBOBOX 3
#define ODT_BUTTON 4
#define ODT_STATIC 5
/*
* Owner draw actions
*/
#define ODA_DRAWENTIRE 0x0001
#define ODA_SELECT 0x0002
#define ODA_FOCUS 0x0004
/*
* Color Types
*/
#define CTLCOLOR_MSGBOX 0
#define CTLCOLOR_EDIT 1
#define CTLCOLOR_LISTBOX 2
#define CTLCOLOR_BTN 3
#define CTLCOLOR_DLG 4
#define CTLCOLOR_SCROLLBAR 5
#define CTLCOLOR_STATIC 6
#define CTLCOLOR_MAX 7
#define COLOR_SCROLLBAR 0
#define COLOR_BACKGROUND 1
#define COLOR_ACTIVECAPTION 2
#define COLOR_INACTIVECAPTION 3
#define COLOR_MENU 4
#define COLOR_WINDOW 5
#define COLOR_WINDOWFRAME 6
#define COLOR_MENUTEXT 7
#define COLOR_WINDOWTEXT 8
#define COLOR_CAPTIONTEXT 9
#define COLOR_ACTIVEBORDER 10
#define COLOR_INACTIVEBORDER 11
#define COLOR_APPWORKSPACE 12
#define COLOR_HIGHLIGHT 13
#define COLOR_HIGHLIGHTTEXT 14
#define COLOR_BTNFACE 15
#define COLOR_BTNSHADOW 16
#define COLOR_GRAYTEXT 17
#define COLOR_BTNTEXT 18
#define COLOR_INACTIVECAPTIONTEXT 19
#define COLOR_BTNHIGHLIGHT 20
#define COLOR_3DDKSHADOW 21
#define COLOR_3DLIGHT 22
#define COLOR_INFOTEXT 23
#define COLOR_INFOBK 24
#define COLOR_HOTLIGHT 26
#define COLOR_GRADIENTACTIVECAPTION 27
#define COLOR_GRADIENTINACTIVECAPTION 28
#define COLOR_MENUHILIGHT 29
#define COLOR_MENUBAR 30
#define COLOR_DESKTOP COLOR_BACKGROUND
#define COLOR_3DFACE COLOR_BTNFACE
#define COLOR_3DSHADOW COLOR_BTNSHADOW
#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT
#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT
#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT
/* StretchBlt() Modes */
#define BLACKONWHITE 1
#define WHITEONBLACK 2
#define COLORONCOLOR 3
#define HALFTONE 4
#define MAXSTRETCHBLTMODE 4
#define STRETCH_ANDSCANS BLACKONWHITE
#define STRETCH_ORSCANS WHITEONBLACK
#define STRETCH_DELETESCANS COLORONCOLOR
#define STRETCH_HALFTONE HALFTONE
/* Binary raster ops */
#define R2_BLACK 1 /* 0 */
#define R2_NOTMERGEPEN 2 /* DPon */
#define R2_MASKNOTPEN 3 /* DPna */
#define R2_NOTCOPYPEN 4 /* PN */
#define R2_MASKPENNOT 5 /* PDna */
#define R2_NOT 6 /* Dn */
#define R2_XORPEN 7 /* DPx */
#define R2_NOTMASKPEN 8 /* DPan */
#define R2_MASKPEN 9 /* DPa */
#define R2_NOTXORPEN 10 /* DPxn */
#define R2_NOP 11 /* D */
#define R2_MERGENOTPEN 12 /* DPno */
#define R2_COPYPEN 13 /* P */
#define R2_MERGEPENNOT 14 /* PDno */
#define R2_MERGEPEN 15 /* DPo */
#define R2_WHITE 16 /* 1 */
#define R2_LAST 16
/* Brush Styles */
#define BS_SOLID 0
#define BS_NULL 1
#define BS_HOLLOW BS_NULL
#define BS_HATCHED 2
#define BS_PATTERN 3
#define BS_INDEXED 4
#define BS_DIBPATTERN 5
#define BS_DIBPATTERNPT 6
#define BS_PATTERN8X8 7
#define BS_DIBPATTERN8X8 8
#define BS_MONOPATTERN 9
/* palette entry flags */
#define PC_RESERVED 0x01 /* palette index used for animation */
#define PC_EXPLICIT 0x02 /* palette index is explicit to device */
#define PC_NOCOLLAPSE 0x04 /* do not match color to system palette */
/*
* DrawText() Format Flags
*/
#define DT_TOP 0x00000000
#define DT_LEFT 0x00000000
#define DT_CENTER 0x00000001
#define DT_RIGHT 0x00000002
#define DT_VCENTER 0x00000004
#define DT_BOTTOM 0x00000008
#define DT_WORDBREAK 0x00000010
#define DT_SINGLELINE 0x00000020
#define DT_EXPANDTABS 0x00000040
#define DT_TABSTOP 0x00000080
#define DT_NOCLIP 0x00000100
#define DT_EXTERNALLEADING 0x00000200
#define DT_CALCRECT 0x00000400
#define DT_NOPREFIX 0x00000800
#define DT_INTERNAL 0x00001000
/* Text Alignment Options */
#define TA_NOUPDATECP 0
#define TA_UPDATECP 1
#define TA_LEFT 0
#define TA_RIGHT 2
#define TA_CENTER 6
#define TA_TOP 0
#define TA_BOTTOM 8
#define TA_BASELINE 24
/*
* Menu flags for Add/Check/EnableMenuItem()
*/
#define MF_INSERT 0x00000000L
#define MF_CHANGE 0x00000080L
#define MF_APPEND 0x00000100L
#define MF_DELETE 0x00000200L
#define MF_REMOVE 0x00001000L
#define MF_BYCOMMAND 0x00000000L
#define MF_BYPOSITION 0x00000400L
#define MF_SEPARATOR 0x00000800L
#define MF_ENABLED 0x00000000L
#define MF_GRAYED 0x00000001L
#define MF_DISABLED 0x00000002L
#define MF_UNCHECKED 0x00000000L
#define MF_CHECKED 0x00000008L
#define MF_USECHECKBITMAPS 0x00000200L
#define MF_STRING 0x00000000L
#define MF_BITMAP 0x00000004L
#define MF_OWNERDRAW 0x00000100L
#define MF_POPUP 0x00000010L
#define MF_MENUBARBREAK 0x00000020L
#define MF_MENUBREAK 0x00000040L
#define MF_UNHILITE 0x00000000L
#define MF_HILITE 0x00000080L
// CBrush hatch styles
#define HS_HORIZONTAL 0
#define HS_VERTICAL 1
#define HS_FDIAGONAL 2
#define HS_BDIAGONAL 3
#define HS_CROSS 4
#define HS_DIAGCROSS 5
// Constants for the biCompression field
#define BI_RGB 0L
/* tmPitchAndFamily flags */
#define TMPF_FIXED_PITCH 0x01
#define TMPF_VECTOR 0x02
#define TMPF_DEVICE 0x08
#define TMPF_TRUETYPE 0x04
#define ANSI_CHARSET 0
/* 3D border styles */
#define BDR_RAISEDOUTER 0x0001
#define BDR_SUNKENOUTER 0x0002
#define BDR_RAISEDINNER 0x0004
#define BDR_SUNKENINNER 0x0008
#define BDR_OUTER (BDR_RAISEDOUTER | BDR_SUNKENOUTER)
#define BDR_INNER (BDR_RAISEDINNER | BDR_SUNKENINNER)
#define BDR_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER)
#define BDR_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER)
#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER)
#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER)
#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER)
#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER)
/* Border flags */
#define BF_LEFT 0x0001
#define BF_TOP 0x0002
#define BF_RIGHT 0x0004
#define BF_BOTTOM 0x0008
#define BF_TOPLEFT (BF_TOP | BF_LEFT)
#define BF_TOPRIGHT (BF_TOP | BF_RIGHT)
#define BF_BOTTOMLEFT (BF_BOTTOM | BF_LEFT)
#define BF_BOTTOMRIGHT (BF_BOTTOM | BF_RIGHT)
#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM)
#define BF_DIAGONAL 0x0010
// For diagonal lines, the BF_RECT flags specify the end point of the
// vector bounded by the rectangle parameter.
#define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL | BF_TOP | BF_RIGHT)
#define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL | BF_TOP | BF_LEFT)
#define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL | BF_BOTTOM | BF_LEFT)
#define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT)
#define BF_MIDDLE 0x0800 /* Fill in the middle */
#define BF_SOFT 0x1000 /* For softer buttons */
#define BF_ADJUST 0x2000 /* Calculate the space left over */
#define BF_FLAT 0x4000 /* For flat rather than 3D borders */
#define BF_MONO 0x8000 /* For monochrome borders */
/*
* WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
*/
#define HTERROR (-2)
#define HTTRANSPARENT (-1)
#define HTNOWHERE 0
#define HTCLIENT 1
#define HTCAPTION 2
#define HTSYSMENU 3
#define HTGROWBOX 4
#define HTSIZE HTGROWBOX
#define HTMENU 5
#define HTHSCROLL 6
#define HTVSCROLL 7
#define HTMINBUTTON 8
#define HTMAXBUTTON 9
#define HTLEFT 10
#define HTRIGHT 11
#define HTTOP 12
#define HTTOPLEFT 13
#define HTTOPRIGHT 14
#define HTBOTTOM 15
#define HTBOTTOMLEFT 16
#define HTBOTTOMRIGHT 17
#define HTBORDER 18
#define HTREDUCE HTMINBUTTON
#define HTZOOM HTMAXBUTTON
#define HTSIZEFIRST HTLEFT
#define HTSIZELAST HTBOTTOMRIGHT
typedef struct tagBITMAPINFOHEADER {
uint32 biSize;
long biWidth;
long biHeight;
uint16 biPlanes;
uint16 biBitCount;
uint32 biCompression;
uint32 biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
uint32 biClrUsed;
uint32 biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER,
*PBITMAPINFOHEADER;
typedef struct tagRGBQUAD {
byte rgbBlue;
byte rgbGreen;
byte rgbRed;
byte rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;
/* Bitmap Header Definition */
typedef struct tagBITMAP {
int bmType;
int bmWidth;
int bmHeight;
int bmWidthBytes;
uint16 bmPlanes;
uint16 bmBitsPixel;
void * bmBits;
} BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP;
typedef struct tagBITMAPCOREHEADER {
uint32 bcSize; /* used to get to color table */
uint16 bcWidth;
uint16 bcHeight;
uint16 bcPlanes;
uint16 bcBitCount;
} BITMAPCOREHEADER, FAR *LPBITMAPCOREHEADER, *PBITMAPCOREHEADER;
typedef struct tagRGBTRIPLE {
byte rgbtBlue;
byte rgbtGreen;
byte rgbtRed;
} RGBTRIPLE, *PRGBTRIPLE, NEAR *NPRGBTRIPLE, FAR *LPRGBTRIPLE;
typedef struct tagBITMAPCOREINFO {
BITMAPCOREHEADER bmciHeader;
RGBTRIPLE bmciColors[1];
} BITMAPCOREINFO, FAR *LPBITMAPCOREINFO, *PBITMAPCOREINFO;
typedef struct tagPALETTEENTRY {
byte peRed;
byte peGreen;
byte peBlue;
byte peFlags;
} PALETTEENTRY, *PPALETTEENTRY, FAR *LPPALETTEENTRY;
typedef struct tagLOGPALETTE {
uint16 palVersion;
uint16 palNumEntries;
PALETTEENTRY palPalEntry[1];
} LOGPALETTE, *PLOGPALETTE, NEAR *NPLOGPALETTE, FAR *LPLOGPALETTE;
/*
* MEASUREITEMSTRUCT for ownerdraw
*/
typedef struct tagMEASUREITEMSTRUCT {
unsigned int CtlType;
unsigned int CtlID;
unsigned int itemID;
unsigned int itemWidth;
unsigned int itemHeight;
uintptr itemData;
} MEASUREITEMSTRUCT, NEAR *PMEASUREITEMSTRUCT, FAR *LPMEASUREITEMSTRUCT;
/*
* DRAWITEMSTRUCT for ownerdraw
*/
typedef struct tagDRAWITEMSTRUCT {
unsigned int CtlType;
unsigned int CtlID;
unsigned int itemID;
unsigned int itemAction;
unsigned int itemState;
HWND hwndItem;
HDC hDC;
RECT rcItem;
uintptr itemData;
} DRAWITEMSTRUCT, NEAR *PDRAWITEMSTRUCT, FAR *LPDRAWITEMSTRUCT;
/* Logical Brush (or Pattern) */
typedef struct tagLOGBRUSH {
unsigned int lbStyle;
COLORREF lbColor;
uintptr lbHatch;
} LOGBRUSH, *PLOGBRUSH, NEAR *NPLOGBRUSH, FAR *LPLOGBRUSH;
extern int GetDeviceCaps(HDC hdc, int index);
extern HDC CreateCompatibleDC(HDC hdc);
extern int ReleaseDC(HWND hWnd, HDC hDC);
extern bool DeleteDC(HDC hdc);
extern bool DeleteObject(HGDIOBJ ho);
extern HDC GetDC(HWND hWnd);
extern int GetObject(HANDLE h, int c, void *pv);
extern HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
extern bool EndPaint(HWND hWnd, const PAINTSTRUCT *lpPaint);
extern intptr DialogBoxParam(HINSTANCE hInstance,
const char *lpTemplateName, HWND hWndParent,
DLGPROC lpDialogFunc, LPARAM dwInitParam);
extern bool IsWindow(HWND hWnd);
extern bool SetWindowText(HWND hWnd, const char *lpszString);
extern int GetWindowText(HWND hWnd, char *lpszStringBuf, int nMaxCount);
extern bool ScreenToClient(HWND hWnd, LPPOINT lpPoint);
HBITMAP CreateDIBitmap(HDC hdc, CONST BITMAPINFOHEADER *pbmih,
uint32 flInit, CONST void *pjBits, CONST BITMAPINFO *pbmi, unsigned int iUsage);
extern int GetDIBits(HDC hdc, HBITMAP hbm, unsigned int start, unsigned int cLines,
void *lpvBits, LPBITMAPINFO lpbmi, unsigned int usage);
extern HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h);
extern HGDIOBJ GetStockObject(int i);
extern HPALETTE SelectPalette(HDC hdc, HPALETTE hPal, bool bForceBkgd);
extern unsigned int RealizePalette(HDC hdc);
extern bool BitBlt(HDC hdc, int xDest, int yDest, int width, int height,
HDC hdcSrc, int xSrc, int ySrc, uint32 rop);
extern bool StretchBlt(HDC hdcDest, int xDest, int yDest,
int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, uint32 rop);
extern int SetStretchBltMode(HDC hdc, int mode);
extern int StretchDIBits(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight,
int xSrc, int ySrc, int SrcWidth, int SrcHeight,
CONST void *lpBits, CONST BITMAPINFO *lpbmi, unsigned int iUsage, uint32 rop);
extern int GetTextExtent(HDC hdc, const char *text, size_t len);
extern bool GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm);
extern intptr GetWindowWord(HWND hWnd, int nIndex);
extern int AddFontResource(const char *fontName);
extern bool RemoveFontResource(const char *fontName);
extern int SetScrollPos(HWND hWnd, int nBar,
int nPos, bool bRedraw);
extern void SetScrollRange(HWND hWnd, int nBar,
int nMinPos, int nMaxPos, bool bRedraw);
extern bool ClipCursor(const RECT *lpRect);
extern bool GetCursorPos(LPPOINT lpPoint);
extern bool SetCursorPos(int x, int y);
extern bool SetCapture(HWND hWnd);
extern bool ReleaseCapture();
extern HWND GetCapture();
extern HCURSOR LoadCursor(HINSTANCE hInstance,
const char *lpCursorName);
extern HCURSOR SetCursor(HCURSOR hCursor);
extern int ShowCursor(bool bShow);
typedef void (CALLBACK *LINEDDAPROC)(int x, int y, CDC *cdc);
extern bool LineDDA(int x0, int y0, int x1, int y1,
LINEDDAPROC lpProc, CDC *cdc);
extern byte GetRValue(COLORREF color);
extern byte GetGValue(COLORREF color);
extern byte GetBValue(COLORREF color);
extern HWND GetDlgItem(HWND hDlg, int nIDDlgItem);
extern bool EndDialog(HWND hDlg, intptr nResult);
extern bool SetDlgItemInt(HWND hDlg, int nIDDlgItem,
unsigned int uValue, bool bSigned);
extern bool CheckRadioButton(HWND hDlg, int nIDFirstButton,
int nIDLastButton, int nIDCheckButton);
extern uint32 GetSysColor(int nIndex);
extern HBRUSH GetSysColorBrush(int nIndex);
extern bool DestroyMenu(HMENU hMenu);
extern void SetActiveWindow(HWND hWnd);
} // namespace MFC
} // namespace Bagel
#endif

731
engines/bagel/mfc/winnt.h Normal file
View File

@@ -0,0 +1,731 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BAGEL_MFC_WINNT_H
#define BAGEL_MFC_WINNT_H
#include "common/scummsys.h"
namespace Bagel {
namespace MFC {
typedef uint16 SHORT;
typedef uint32 COLORREF;
typedef void *POSITION;
#define RGB_COL(r,g,b) ((COLORREF)(((byte)(r)|((uint16)((byte)(g))<<8))|(((uint32)(byte)(b))<<16)))
#define PALETTERGB(r,g,b) (0x02000000 | RGB_COL(r,g,b))
#define RGB(r,g,b) PALETTERGB(r,g,b)
#define IS_RGB(VAL) ((VAL & 0x02000000) != 0)
#define PAL_DEFAULT 0x0000
#define PAL_ANIMATED 0x0001
#define PAL_EXPLICIT 0x0002
#define HINSTANCE_ERROR (HINSTANCE)32
//
// Success codes
//
#define S_OK ((HRESULT)0L)
#define S_FALSE ((HRESULT)1L)
typedef void *HANDLE;
typedef long HRESULT;
typedef uint32 LCID;
typedef uint32 *PLCID;
typedef uint16 LANGID;
typedef uint32 (*APPLICATION_RECOVERY_CALLBACK)(void *pvParameter);
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
/* Local Memory Flags */
#define LMEM_FIXED 0x0000
#define LMEM_MOVEABLE 0x0002
#define LMEM_NOCOMPACT 0x0010
#define LMEM_NODISCARD 0x0020
#define LMEM_ZEROINIT 0x0040
#define LMEM_MODIFY 0x0080
#define LMEM_DISCARDABLE 0x0F00
#define LMEM_VALID_FLAGS 0x0F72
#define LMEM_INVALID_HANDLE 0x8000
#define LHND (LMEM_MOVEABLE | LMEM_ZEROINIT)
#define LPTR (LMEM_FIXED | LMEM_ZEROINIT)
//
// Define access rights to files and directories
//
//
// The FILE_READ_DATA and FILE_WRITE_DATA constants are also defined in
// devioctl.h as FILE_READ_ACCESS and FILE_WRITE_ACCESS. The values for these
// constants *MUST* always be in sync.
// The values are redefined in devioctl.h because they must be available to
// both DOS and NT.
//
#define FILE_READ_DATA ( 0x0001 ) // file & pipe
#define FILE_LIST_DIRECTORY ( 0x0001 ) // directory
#define FILE_WRITE_DATA ( 0x0002 ) // file & pipe
#define FILE_ADD_FILE ( 0x0002 ) // directory
#define FILE_APPEND_DATA ( 0x0004 ) // file
#define FILE_ADD_SUBDIRECTORY ( 0x0004 ) // directory
#define FILE_CREATE_PIPE_INSTANCE ( 0x0004 ) // named pipe
#define FILE_READ_EA ( 0x0008 ) // file & directory
#define FILE_WRITE_EA ( 0x0010 ) // file & directory
#define FILE_EXECUTE ( 0x0020 ) // file
#define FILE_TRAVERSE ( 0x0020 ) // directory
#define FILE_DELETE_CHILD ( 0x0040 ) // directory
#define FILE_READ_ATTRIBUTES ( 0x0080 ) // all
#define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // all
#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ |\
FILE_READ_DATA |\
FILE_READ_ATTRIBUTES |\
FILE_READ_EA |\
SYNCHRONIZE)
#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\
FILE_WRITE_DATA |\
FILE_WRITE_ATTRIBUTES |\
FILE_WRITE_EA |\
FILE_APPEND_DATA |\
SYNCHRONIZE)
#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
FILE_READ_ATTRIBUTES |\
FILE_EXECUTE |\
SYNCHRONIZE)
#define FILE_SHARE_READ 0x00000001
#define FILE_SHARE_WRITE 0x00000002
#define FILE_SHARE_DELETE 0x00000004
#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
#define FILE_ATTRIBUTE_DEVICE 0x00000040
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
#define FILE_ATTRIBUTE_OFFLINE 0x00001000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
#define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x00008000
#define FILE_ATTRIBUTE_VIRTUAL 0x00010000
#define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000
#define FILE_ATTRIBUTE_EA 0x00040000
#define FILE_ATTRIBUTE_PINNED 0x00080000
#define FILE_ATTRIBUTE_UNPINNED 0x00100000
#define FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000
#define FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000
#define TREE_CONNECT_ATTRIBUTE_PRIVACY 0x00004000
#define TREE_CONNECT_ATTRIBUTE_INTEGRITY 0x00008000
#define TREE_CONNECT_ATTRIBUTE_GLOBAL 0x00000004
#define TREE_CONNECT_ATTRIBUTE_PINNED 0x00000002
#define FILE_ATTRIBUTE_STRICTLY_SEQUENTIAL 0x20000000
#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004
#define FILE_NOTIFY_CHANGE_SIZE 0x00000008
#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020
#define FILE_NOTIFY_CHANGE_CREATION 0x00000040
#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100
#define FILE_ACTION_ADDED 0x00000001
#define FILE_ACTION_REMOVED 0x00000002
#define FILE_ACTION_MODIFIED 0x00000003
#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004
#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005
#define MAILSLOT_NO_MESSAGE ((uint32)-1)
#define MAILSLOT_WAIT_FOREVER ((uint32)-1)
#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
#define FILE_CASE_PRESERVED_NAMES 0x00000002
#define FILE_UNICODE_ON_DISK 0x00000004
#define FILE_PERSISTENT_ACLS 0x00000008
#define FILE_FILE_COMPRESSION 0x00000010
#define FILE_VOLUME_QUOTAS 0x00000020
#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
#define FILE_RETURNS_CLEANUP_RESULT_INFO 0x00000200
#define FILE_SUPPORTS_POSIX_UNLINK_RENAME 0x00000400
#define FILE_SUPPORTS_BYPASS_IO 0x00000800
#define FILE_SUPPORTS_STREAM_SNAPSHOTS 0x00001000
#define FILE_SUPPORTS_CASE_SENSITIVE_DIRS 0x00002000
#define FILE_VOLUME_IS_COMPRESSED 0x00008000
#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
#define FILE_SUPPORTS_ENCRYPTION 0x00020000
#define FILE_NAMED_STREAMS 0x00040000
#define FILE_READ_ONLY_VOLUME 0x00080000
#define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000
#define FILE_SUPPORTS_TRANSACTIONS 0x00200000
#define FILE_SUPPORTS_HARD_LINKS 0x00400000
#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000
#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
#define FILE_SUPPORTS_USN_JOURNAL 0x02000000
#define FILE_SUPPORTS_INTEGRITY_STREAMS 0x04000000
#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000
#define FILE_SUPPORTS_SPARSE_VDL 0x10000000
#define FILE_DAX_VOLUME 0x20000000
#define FILE_SUPPORTS_GHOSTING 0x40000000
/*
* RedrawWindow() flags
*/
#define RDW_INVALIDATE 0x0001
#define RDW_INTERNALPAINT 0x0002
#define RDW_ERASE 0x0004
#define RDW_VALIDATE 0x0008
#define RDW_NOINTERNALPAINT 0x0010
#define RDW_NOERASE 0x0020
#define RDW_NOCHILDREN 0x0040
#define RDW_ALLCHILDREN 0x0080
#define RDW_UPDATENOW 0x0100
#define RDW_ERASENOW 0x0200
#define RDW_FRAME 0x0400
#define RDW_NOFRAME 0x0800
/*
* EnableScrollBar() flags
*/
#define ESB_ENABLE_BOTH 0x0000
#define ESB_DISABLE_BOTH 0x0003
#define ESB_DISABLE_LEFT 0x0001
#define ESB_DISABLE_RIGHT 0x0002
#define ESB_DISABLE_UP 0x0001
#define ESB_DISABLE_DOWN 0x0002
#define ESB_DISABLE_LTUP ESB_DISABLE_LEFT
#define ESB_DISABLE_RTDN ESB_DISABLE_RIGHT
#define SIF_RANGE 0x0001
#define SIF_PAGE 0x0002
#define SIF_POS 0x0004
#define SIF_DISABLENOSCROLL 0x0008
#define SIF_TRACKPOS 0x0010
#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
/*
* GetWindow() Constants
*/
#define GW_HWNDFIRST 0
#define GW_HWNDLAST 1
#define GW_HWNDNEXT 2
#define GW_HWNDPREV 3
#define GW_OWNER 4
#define GW_CHILD 5
#if(WINVER <= 0x0400)
#define GW_MAX 5
#else
#define GW_ENABLEDPOPUP 6
#define GW_MAX 6
#endif
/*
* MessageBox() Flags
*/
#define MB_OK 0x00000000L
#define MB_OKCANCEL 0x00000001L
#define MB_ABORTRETRYIGNORE 0x00000002L
#define MB_YESNOCANCEL 0x00000003L
#define MB_YESNO 0x00000004L
#define MB_RETRYCANCEL 0x00000005L
/*
* Scroll Bar Constants
*/
#define SB_HORZ 0
#define SB_VERT 1
#define SB_CTL 2
#define SB_BOTH 3
/*
* Scroll Bar Commands
*/
#define SB_LINEUP 0
#define SB_LINELEFT 0
#define SB_LINEDOWN 1
#define SB_LINERIGHT 1
#define SB_PAGEUP 2
#define SB_PAGELEFT 2
#define SB_PAGEDOWN 3
#define SB_PAGERIGHT 3
#define SB_THUMBPOSITION 4
#define SB_THUMBTRACK 5
#define SB_TOP 6
#define SB_LEFT 6
#define SB_BOTTOM 7
#define SB_RIGHT 7
#define SB_ENDSCROLL 8
/*
* Scroll Bar Styles
*/
#define SBS_HORZ 0x0000L
#define SBS_VERT 0x0001L
#define SBS_TOPALIGN 0x0002L
#define SBS_LEFTALIGN 0x0002L
#define SBS_BOTTOMALIGN 0x0004L
#define SBS_RIGHTALIGN 0x0004L
#define SBS_SIZEBOXTOPLEFTALIGN 0x0002L
#define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L
#define SBS_SIZEBOX 0x0008L
// General error / prompt strings
#define AFX_IDP_INVALID_FILENAME 0xF100
#define AFX_IDP_FAILED_TO_OPEN_DOC 0xF101
#define AFX_IDP_FAILED_TO_SAVE_DOC 0xF102
/*
* Dialog Box Command IDs
*/
#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7
#define IDCLOSE 8
#define IDHELP 9
#define IDTRYAGAIN 10
#define IDCONTINUE 11
#define IDTIMEOUT 32000
/*
* User Button Notification Codes
*/
#define BN_CLICKED 0
#define BN_PAINT 1
#define BN_HILITE 2
#define BN_UNHILITE 3
#define BN_DISABLE 4
#define BN_DOUBLECLICKED 5
#define BN_PUSHED BN_HILITE
#define BN_UNPUSHED BN_UNHILITE
#define BN_DBLCLK BN_DOUBLECLICKED
#define BN_SETFOCUS 6
#define BN_KILLFOCUS 7
/*
* Window Styles
*/
#define WS_OVERLAPPED 0x00000000L
#define WS_POPUP 0x80000000L
#define WS_CHILD 0x40000000L
#define WS_MINIMIZE 0x20000000L
#define WS_VISIBLE 0x10000000L
#define WS_DISABLED 0x08000000L
#define WS_CLIPSIBLINGS 0x04000000L
#define WS_CLIPCHILDREN 0x02000000L
#define WS_MAXIMIZE 0x01000000L
#define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */
#define WS_BORDER 0x00800000L
#define WS_DLGFRAME 0x00400000L
#define WS_VSCROLL 0x00200000L
#define WS_HSCROLL 0x00100000L
#define WS_SYSMENU 0x00080000L
#define WS_THICKFRAME 0x00040000L
#define WS_GROUP 0x00020000L
#define WS_TABSTOP 0x00010000L
#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L
#define WS_TILED WS_OVERLAPPED
#define WS_ICONIC WS_MINIMIZE
#define WS_SIZEBOX WS_THICKFRAME
#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
/*
* Common Window Styles
*/
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \
WS_CAPTION | \
WS_SYSMENU | \
WS_THICKFRAME | \
WS_MINIMIZEBOX | \
WS_MAXIMIZEBOX)
#define WS_POPUPWINDOW (WS_POPUP | \
WS_BORDER | \
WS_SYSMENU)
#define WS_CHILDWINDOW (WS_CHILD)
// Frame window styles
#define FWS_ADDTOTITLE 0x00008000L // Modify title based on content
#define FWS_PREFIXTITLE 0x00004000L // Show document name before app name
#define FWS_SNAPTOBARS 0x00002000L // Snap size to size of contained bars
/*
* Edit Control Styles
*/
#define ES_LEFT 0x0000L
#define ES_CENTER 0x0001L
#define ES_RIGHT 0x0002L
#define ES_MULTILINE 0x0004L
#define ES_UPPERCASE 0x0008L
#define ES_LOWERCASE 0x0010L
#define ES_PASSWORD 0x0020L
#define ES_AUTOVSCROLL 0x0040L
#define ES_AUTOHSCROLL 0x0080L
#define ES_NOHIDESEL 0x0100L
#define ES_OEMCONVERT 0x0400L
#define ES_READONLY 0x0800L
#define ES_WANTRETURN 0x1000L
#define ES_NUMBER 0x2000L
/*
* SetWindowsHook() codes
*/
#define WH_MIN (-1)
#define WH_MSGFILTER (-1)
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD 2
#define WH_GETMESSAGE 3
#define WH_CALLWNDPROC 4
#define WH_CBT 5
#define WH_SYSMSGFILTER 6
#define WH_MOUSE 7
/*
* Key State Masks for Mouse Messages
*/
#define MK_LBUTTON 0x0001
#define MK_RBUTTON 0x0002
#define MK_SHIFT 0x0004
#define MK_CONTROL 0x0008
#define MK_MBUTTON 0x0010
#define MK_XBUTTON1 0x0020
#define MK_XBUTTON2 0x0040
/*
* GetSystemMetrics() codes
*/
#define SM_CXSCREEN 0
#define SM_CYSCREEN 1
#define SM_CXVSCROLL 2
#define SM_CYHSCROLL 3
#define SM_CYCAPTION 4
#define SM_CXBORDER 5
#define SM_CYBORDER 6
#define SM_CXDLGFRAME 7
#define SM_CYDLGFRAME 8
#define SM_CYVTHUMB 9
#define SM_CXHTHUMB 10
#define SM_CXICON 11
#define SM_CYICON 12
#define SM_CXCURSOR 13
#define SM_CYCURSOR 14
#define SM_CYMENU 15
#define SM_CXFULLSCREEN 16
#define SM_CYFULLSCREEN 17
#define SM_CYKANJIWINDOW 18
#define SM_MOUSEPRESENT 19
#define SM_CYVSCROLL 20
#define SM_CXHSCROLL 21
#define SM_DEBUG 22
#define SM_SWAPBUTTON 23
#define SM_RESERVED1 24
#define SM_RESERVED2 25
#define SM_RESERVED3 26
#define SM_RESERVED4 27
#define SM_CXMIN 28
#define SM_CYMIN 29
#define SM_CXSIZE 30
#define SM_CYSIZE 31
#define SM_CXFRAME 32
#define SM_CYFRAME 33
#define SM_CXMINTRACK 34
#define SM_CYMINTRACK 35
#define SM_CXDOUBLECLK 36
#define SM_CYDOUBLECLK 37
#define SM_CXICONSPACING 38
#define SM_CYICONSPACING 39
#define SM_MENUDROPALIGNMENT 40
#define SM_PENWINDOWS 41
#define SM_DBCSENABLED 42
#define SM_CMOUSEBUTTONS 43
#define SM_CXFIXEDFRAME SM_CXDLGFRAME /* ;win40 name change */
#define SM_CYFIXEDFRAME SM_CYDLGFRAME /* ;win40 name change */
#define SM_CXSIZEFRAME SM_CXFRAME /* ;win40 name change */
#define SM_CYSIZEFRAME SM_CYFRAME /* ;win40 name change */
#define SM_SECURE 44
#define SM_CXEDGE 45
#define SM_CYEDGE 46
#define SM_CXMINSPACING 47
#define SM_CYMINSPACING 48
#define SM_CXSMICON 49
#define SM_CYSMICON 50
#define SM_CYSMCAPTION 51
#define SM_CXSMSIZE 52
#define SM_CYSMSIZE 53
#define SM_CXMENUSIZE 54
#define SM_CYMENUSIZE 55
#define SM_ARRANGE 56
#define SM_CXMINIMIZED 57
#define SM_CYMINIMIZED 58
#define SM_CXMAXTRACK 59
#define SM_CYMAXTRACK 60
#define SM_CXMAXIMIZED 61
#define SM_CYMAXIMIZED 62
#define SM_NETWORK 63
#define SM_CLEANBOOT 67
#define SM_CXDRAG 68
#define SM_CYDRAG 69
#define SM_SHOWSOUNDS 70
#define SM_CXMENUCHECK 71 /* Use instead of GetMenuCheckMarkDimensions()! */
#define SM_CYMENUCHECK 72
#define SM_SLOWMACHINE 73
#define SM_MIDEASTENABLED 74
#define SM_MOUSEWHEELPRESENT 75
#define SM_XVIRTUALSCREEN 76
#define SM_YVIRTUALSCREEN 77
#define SM_CXVIRTUALSCREEN 78
#define SM_CYVIRTUALSCREEN 79
#define SM_CMONITORS 80
#define SM_SAMEDISPLAYFORMAT 81
#define SM_IMMENABLED 82
#define SM_CXFOCUSBORDER 83
#define SM_CYFOCUSBORDER 84
#define SM_TABLETPC 86
#define SM_MEDIACENTER 87
#define SM_STARTER 88
#define SM_SERVERR2 89
#define SM_MOUSEHORIZONTALWHEELPRESENT 91
#define SM_CXPADDEDBORDER 92
#define SM_DIGITIZER 94
#define SM_MAXIMUMTOUCHES 95
#define SM_CMETRICS 97
#define SM_REMOTESESSION 0x1000
#define SM_SHUTTINGDOWN 0x2000
#define SM_REMOTECONTROL 0x2001
#define SM_CARETBLINKINGENABLED 0x2002
#define SM_CONVERTIBLESLATEMODE 0x2003
#define SM_SYSTEMDOCKED 0x2004
/* Mapping Modes */
#define MM_TEXT 1
#define MM_LOMETRIC 2
#define MM_HIMETRIC 3
#define MM_LOENGLISH 4
#define MM_HIENGLISH 5
#define MM_TWIPS 6
#define MM_ISOTROPIC 7
#define MM_ANISOTROPIC 8
/* Min and Max Mapping Mode values */
#define MM_MIN MM_TEXT
#define MM_MAX MM_ANISOTROPIC
#define MM_MAX_FIXEDSCALE MM_TWIPS
/*
* System Menu Command Values
*/
#define SC_SIZE 0xF000
#define SC_MOVE 0xF010
#define SC_MINIMIZE 0xF020
#define SC_MAXIMIZE 0xF030
#define SC_NEXTWINDOW 0xF040
#define SC_PREVWINDOW 0xF050
#define SC_CLOSE 0xF060
#define SC_VSCROLL 0xF070
#define SC_HSCROLL 0xF080
#define SC_MOUSEMENU 0xF090
#define SC_KEYMENU 0xF100
#define SC_ARRANGE 0xF110
#define SC_RESTORE 0xF120
#define SC_TASKLIST 0xF130
#define SC_SCREENSAVE 0xF140
#define SC_HOTKEY 0xF150
#define SC_DEFAULT 0xF160
#define SC_MONITORPOWER 0xF170
#define SC_CONTEXTHELP 0xF180
#define SC_SEPARATOR 0xF00F
/*
* Predefined Resource Types
*/
#define MAKEINTRESOURCE(i) ((char *)((uintptr)((uint16)(i))))
#define RT_CURSOR MAKEINTRESOURCE(1)
#define RT_BITMAP MAKEINTRESOURCE(2)
#define RT_ICON MAKEINTRESOURCE(3)
#define RT_MENU MAKEINTRESOURCE(4)
#define RT_DIALOG MAKEINTRESOURCE(5)
#define RT_STRING MAKEINTRESOURCE(6)
#define RT_FONTDIR MAKEINTRESOURCE(7)
#define RT_FONT MAKEINTRESOURCE(8)
#define RT_ACCELERATOR MAKEINTRESOURCE(9)
#define RT_RCDATA MAKEINTRESOURCE(10)
#define RT_MESSAGETABLE MAKEINTRESOURCE(11)
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
#define REFIID const IID &
/* PolyFill() Modes */
#define ALTERNATE 1
#define WINDING 2
#define POLYFILL_LAST 2
/* Region Flags */
#define ERROR 0
#define NULLREGION 1
#define SIMPLEREGION 2
#define COMPLEXREGION 3
#define RGN_ERROR ERROR
/*
* Hook Codes
*/
#define HC_ACTION 0
#define HC_GETNEXT 1
#define HC_SKIP 2
#define HC_NOREMOVE 3
#define HC_NOREM HC_NOREMOVE
#define HC_SYSMODALON 4
#define HC_SYSMODALOFF 5
// parts of Main Frame
#define AFX_IDW_PANE_FIRST 0xE900 // first pane (256 max)
#define AFX_IDW_PANE_LAST 0xE9ff
#define AFX_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
#define AFX_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
#define AFX_IDW_SIZE_BOX 0xEA20 // size box for splitters
#define AFX_IDW_PANE_SAVE 0xEA21 // to shift AFX_IDW_PANE_FIRST
#define AFX_WS_DEFAULT_VIEW (WS_CHILD | WS_VISIBLE)
/*
* Dialog Codes
*/
#define DLGC_WANTARROWS 0x0001 /* Control wants arrow keys */
#define DLGC_WANTTAB 0x0002 /* Control wants tab keys */
#define DLGC_WANTALLKEYS 0x0004 /* Control wants all keys */
#define DLGC_WANTMESSAGE 0x0004 /* Pass message to control */
#define DLGC_HASSETSEL 0x0008 /* Understands EM_SETSEL message */
#define DLGC_DEFPUSHBUTTON 0x0010 /* Default pushbutton */
#define DLGC_UNDEFPUSHBUTTON 0x0020 /* Non-default pushbutton */
#define DLGC_RADIOBUTTON 0x0040 /* Radio button */
#define DLGC_WANTCHARS 0x0080 /* Want WM_CHAR messages */
#define DLGC_STATIC 0x0100 /* Static item: don't include */
#define DLGC_BUTTON 0x2000 /* Button item: can be checked */
typedef struct tagTEXTMETRICA {
long tmHeight = 0;
long tmAscent = 0;
long tmDescent = 0;
long tmInternalLeading = 0;
long tmExternalLeading = 0;
long tmAveCharWidth = 0;
long tmMaxCharWidth = 0;
long tmWeight = 0;
long tmOverhang = 0;
long tmDigitizedAspectX = 0;
long tmDigitizedAspectY = 0;
byte tmFirstChar = 0;
byte tmLastChar = 0;
byte tmDefaultChar = 0;
byte tmBreakChar = 0;
byte tmItalic = 0;
byte tmUnderlined = 0;
byte tmStruckOut = 0;
byte tmPitchAndFamily = 0;
byte tmCharSet = 0;
} TEXTMETRIC, *PTEXTMETRIC, *LPTEXTMETRIC;
typedef struct tagGCP_RESULTS {
} GCP_RESULTS, *LPGCP_RESULTS;
struct LOGFONT {
long lfHeight;
long lfWidth;
long lfEscapement;
long lfOrientation;
long lfWeight;
byte lfItalic;
byte lfUnderline;
byte lfStrikeOut;
byte lfCharSet;
byte lfOutPrecision;
byte lfClipPrecision;
byte lfQuality;
byte lfPitchAndFamily;
char lfFaceName[32];
};
typedef LOGFONT *LPLOGFONT;
typedef struct tagSCROLLINFO {
unsigned int cbSize;
unsigned int fMask;
int nMin;
int nMax;
unsigned int nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, *LPSCROLLINFO;
typedef const SCROLLINFO *LPCSCROLLINFO;
} // namespace MFC
} // namespace Bagel
#endif

1268
engines/bagel/mfc/wnd.cpp Normal file

File diff suppressed because it is too large Load Diff