diff --git a/win9x/dialog/d_screen.cpp b/win9x/dialog/d_screen.cpp index c32063f..91b2f88 100644 --- a/win9x/dialog/d_screen.cpp +++ b/win9x/dialog/d_screen.cpp @@ -8,8 +8,11 @@ #include "resource.h" #include #include -#include "misc/PropProc.h" +#include "xmil.h" +#include "scrnmng.h" #include "sysmng.h" +#include "misc/PropProc.h" +#include "dialogs.h" #include "pccore.h" #include "palettes.h" @@ -53,6 +56,7 @@ BOOL ScrOptVideoPage::OnInitDialog() return TRUE; } + /** * ユーザーが OK のボタン (IDOK ID がのボタン) をクリックすると呼び出されます */ @@ -109,6 +113,109 @@ LRESULT ScrOptVideoPage::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam) return CPropPageProc::WindowProc(nMsg, wParam, lParam); } + + +// ---- + +/** + * @brief Fullscreen ページ + */ +class ScrOptFullscreenPage : public CPropPageProc +{ +public: + ScrOptFullscreenPage(); + virtual ~ScrOptFullscreenPage(); + +protected: + virtual BOOL OnInitDialog(); + virtual void OnOK(); + virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); + +private: + CNp2ComboBox m_zoom; //!< ズーム +}; + +static const CBPARAM s_cpZoom[] = +{ + {MAKEINTRESOURCE(IDS_ZOOM_NONE), 0}, + {MAKEINTRESOURCE(IDS_ZOOM_FIXEDASPECT), 1}, + {MAKEINTRESOURCE(IDS_ZOOM_ADJUSTASPECT), 2}, + {MAKEINTRESOURCE(IDS_ZOOM_FULL), 3}, +}; + +/** + * コンストラクタ + */ +ScrOptFullscreenPage::ScrOptFullscreenPage() + : CPropPageProc(IDD_SCROPT_FULLSCREEN) +{ +} + +/** + * デストラクタ + */ +ScrOptFullscreenPage::~ScrOptFullscreenPage() +{ +} + +/** + * このメソッドは WM_INITDIALOG のメッセージに応答して呼び出されます + * @retval TRUE 最初のコントロールに入力フォーカスを設定 + * @retval FALSE 既に設定済 + */ +BOOL ScrOptFullscreenPage::OnInitDialog() +{ + const UINT8 c = xmiloscfg.fscrnmod; + CheckDlgButton(IDC_FULLSCREEN_SAMEBPP, (c & FSCRNMOD_SAMEBPP) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_FULLSCREEN_SAMERES, (c & FSCRNMOD_SAMERES) ? BST_CHECKED : BST_UNCHECKED); + + m_zoom.SubclassDlgItem(IDC_FULLSCREEN_ZOOM, this); + m_zoom.Add(s_cpZoom, _countof(s_cpZoom)); + m_zoom.SetCurItemData(c & 3); + m_zoom.EnableWindow((c & FSCRNMOD_SAMERES) ? TRUE : FALSE); + + return TRUE; +} + +/** + * ユーザーが OK のボタン (IDOK ID がのボタン) をクリックすると呼び出されます + */ +void ScrOptFullscreenPage::OnOK() +{ + UINT8 c = 0; + if (IsDlgButtonChecked(IDC_FULLSCREEN_SAMEBPP) != BST_UNCHECKED) + { + c |= FSCRNMOD_SAMEBPP; + } + if (IsDlgButtonChecked(IDC_FULLSCREEN_SAMERES) != BST_UNCHECKED) + { + c |= FSCRNMOD_SAMERES; + } + c |= m_zoom.GetCurItemData(xmiloscfg.fscrnmod & 3); + if (xmiloscfg.fscrnmod != c) + { + xmiloscfg.fscrnmod = c; + ::sysmng_update(SYS_UPDATEOSCFG); + } +} + + +/** + * ユーザーがメニューの項目を選択したときに、フレームワークによって呼び出されます + * @param[in] wParam パラメタ + * @param[in] lParam パラメタ + * @retval TRUE アプリケーションがこのメッセージを処理した + */ +BOOL ScrOptFullscreenPage::OnCommand(WPARAM wParam, LPARAM lParam) +{ + if (LOWORD(wParam) == IDC_FULLSCREEN_SAMERES) + { + m_zoom.EnableWindow((IsDlgButtonChecked(IDC_FULLSCREEN_SAMERES) != BST_UNCHECKED) ? TRUE : FALSE); + return TRUE; + } + return FALSE; +} + /** * スクリーン設定 * @param[in] hWnd 親ウィンドウ @@ -120,6 +227,9 @@ void dialog_scropt(HWND hWnd) ScrOptVideoPage video; hpsp.push_back(::CreatePropertySheetPage(&video.m_psp)); + ScrOptFullscreenPage fullscreen; + hpsp.push_back(::CreatePropertySheetPage(&fullscreen.m_psp)); + std::tstring rTitle(LoadTString(IDS_SCREENOPTION)); PROPSHEETHEADER psh; diff --git a/win9x/dialog/dialogs.cpp b/win9x/dialog/dialogs.cpp new file mode 100644 index 0000000..769e741 --- /dev/null +++ b/win9x/dialog/dialogs.cpp @@ -0,0 +1,59 @@ +/** + * @file dialogs.cpp + * @brief ダイアログ ヘルパーの動作の定義を行います + */ + +#include "compiler.h" +#include "dialogs.h" +#include "strres.h" + +void CNp2ComboBox::Add(const UINT32* lpValues, UINT nCount) +{ + for (UINT i = 0; i < nCount; i++) + { + TCHAR str[16]; + wsprintf(str, str_u, lpValues[i]); + InsertString(GetCount(), str); + } +} + +void CNp2ComboBox::Add(PCCBPARAM pcItem, UINT nCount) +{ + for (UINT i = 0; i = 0) + { + SetItemData(nIndex, nItemData); + } +} + +void CNp2ComboBox::SetCurItemData(UINT32 nValue) +{ + const int nItems = GetCount(); + for (int i = 0; i < nItems; i++) + { + if (GetItemData(i) == nValue) + { + SetCurSel(i); + break; + } + } +} + +UINT32 CNp2ComboBox::GetCurItemData(UINT32 nDefault) const +{ + int nIndex = GetCurSel(); + if (nIndex >= 0) + { + return GetItemData(nIndex); + } + return nDefault; +} diff --git a/win9x/dialog/dialogs.h b/win9x/dialog/dialogs.h new file mode 100644 index 0000000..76c6a35 --- /dev/null +++ b/win9x/dialog/dialogs.h @@ -0,0 +1,30 @@ +/** + * @file dialogs.h + * @brief ダイアログ ヘルパーの宣言およびインターフェイスの定義をします + */ + +#pragma once + +#include "misc/DlgProc.h" + +struct tagCBParam +{ + LPCTSTR lpcszString; + int nItemData; +}; +typedef struct tagCBParam CBPARAM; +typedef struct tagCBParam *PCBPARAM; +typedef const struct tagCBParam *PCCBPARAM; + +/** + * @brief コンボ ボックス クラス + */ +class CNp2ComboBox : public CComboBoxProc +{ +public: + void Add(const UINT32* lpValues, UINT nCount); + void Add(PCCBPARAM pcItem, UINT nCount); + void Add(LPCTSTR lpString, DWORD_PTR nItemData); + void SetCurItemData(UINT32 nValue); + UINT32 GetCurItemData(UINT32 nDefault) const; +}; diff --git a/win9x/ini.cpp b/win9x/ini.cpp index dff2f95..84ded13 100644 --- a/win9x/ini.cpp +++ b/win9x/ini.cpp @@ -302,6 +302,7 @@ static const TCHAR s_szIniTitle[] = TEXT("Xmillennium"); //!< enum { PFRO_BOOL = PFFLAG_RO + PFTYPE_BOOL, + PFRO_UINT8 = PFFLAG_RO + PFTYPE_UINT8, PFRO_HEX32 = PFFLAG_RO + PFTYPE_HEX32 }; @@ -361,6 +362,9 @@ static const PFTBL s_IniItems[] = PFAND("clock_up", PFRO_HEX32, &xmiloscfg.clockcolor1, 0xffffff), PFAND("clock_dn", PFRO_HEX32, &xmiloscfg.clockcolor2, 0xffffff), #endif /* defined(SUPPORT_DCLOCK) */ + + PFVAL("fscrnbpp", PFRO_UINT8, &xmiloscfg.fscrnbpp), + PFVAL("fscrnmod", PFTYPE_HEX8, &xmiloscfg.fscrnmod), }; //! .ini 拡張子 diff --git a/win9x/resource.h b/win9x/resource.h index de44377..a06aa04 100644 --- a/win9x/resource.h +++ b/win9x/resource.h @@ -8,6 +8,7 @@ #define IDD_NEWDISK 104 #define IDD_ABOUT 105 #define IDD_SCROPT 106 +#define IDD_SCROPT_FULLSCREEN 107 #define IDR_SYS 201 #define IDR_STAT 202 #define IDR_FDD0MENU 203 @@ -28,6 +29,9 @@ #define IDC_MAKE2D 1008 #define IDC_MAKE2HD 1009 #define IDC_XMILVER 1010 +#define IDC_FULLSCREEN_SAMEBPP 1101 +#define IDC_FULLSCREEN_SAMERES 1102 +#define IDC_FULLSCREEN_ZOOM 1103 #define IDS_APP_NAME 30001 #define IDS_CAPTION_KEYDISP 30101 #define IDS_CAPTION_SOFTKBD 30102 @@ -47,6 +51,10 @@ #define IDS_X1FEXT 31032 #define IDS_X1FFILTER 31033 #define IDS_SCREENOPTION 31051 +#define IDS_ZOOM_NONE 31052 +#define IDS_ZOOM_FIXEDASPECT 31053 +#define IDS_ZOOM_ADJUSTASPECT 31054 +#define IDS_ZOOM_FULL 31055 #define IDM_IPLRESET 40000 #define IDM_NMIRESET 40001 #define IDM_CONFIG 40002 diff --git a/win9x/scrnmng.cpp b/win9x/scrnmng.cpp index 7abaeab..c17f136 100644 --- a/win9x/scrnmng.cpp +++ b/win9x/scrnmng.cpp @@ -54,6 +54,8 @@ typedef struct { int menusize; RECT scrn; RECT rect; + RECT scrnclip; + RECT rectclip; PALETTEENTRY pal[256]; } DDRAW; @@ -143,10 +145,67 @@ static void renewalclientsize(BOOL winloc) { if (ddraw.scrnmode & SCRNMODE_FULLSCREEN) { ddraw.rect.right = width; ddraw.rect.bottom = height; - ddraw.scrn.left = (ddraw.width - width) / 2; - ddraw.scrn.top = (ddraw.height - height) / 2; - ddraw.scrn.right = ddraw.scrn.left + width; - ddraw.scrn.bottom = ddraw.scrn.top + height; + scrnwidth = width; + scrnheight = height; + const UINT8 fscrnmod = xmiloscfg.fscrnmod & FSCRNMOD_ASPECTMASK; + switch (fscrnmod) + { + default: + case FSCRNMOD_NORESIZE: + break; + + case FSCRNMOD_ASPECTFIX8: + scrnwidth = (ddraw.width << 3) / width; + scrnheight = (ddraw.height << 3) / height; + multiple = min(scrnwidth, scrnheight); + scrnwidth = (width * multiple) >> 3; + scrnheight = (height * multiple) >> 3; + break; + + case FSCRNMOD_ASPECTFIX: + scrnwidth = ddraw.width; + scrnheight = (scrnwidth * height) / width; + if (scrnheight >= ddraw.height) { + scrnheight = ddraw.height; + scrnwidth = (scrnheight * width) / height; + } + break; + + case FSCRNMOD_LARGE: + scrnwidth = ddraw.width; + scrnheight = ddraw.height; + break; + } + ddraw.scrn.left = (ddraw.width - scrnwidth) / 2; + ddraw.scrn.top = (ddraw.height - scrnheight) / 2; + ddraw.scrn.right = ddraw.scrn.left + scrnwidth; + ddraw.scrn.bottom = ddraw.scrn.top + scrnheight; + + // メニュー表示時の描画領域 + ddraw.rectclip = ddraw.rect; + ddraw.scrnclip = ddraw.scrn; + if (ddraw.scrnclip.top < ddraw.menusize) { + ddraw.scrnclip.top = ddraw.menusize; + int tmpcy = ddraw.height - ddraw.menusize; + if (scrnheight > tmpcy) { + switch(fscrnmod) { + default: + case FSCRNMOD_NORESIZE: + tmpcy = min(tmpcy, height); + ddraw.rectclip.bottom = tmpcy; + break; + + case FSCRNMOD_ASPECTFIX8: + case FSCRNMOD_ASPECTFIX: + ddraw.rectclip.bottom = (tmpcy * height) / scrnheight; + break; + + case FSCRNMOD_LARGE: + break; + } + } + ddraw.scrnclip.bottom = ddraw.menusize + tmpcy; + } } else { multiple = 8; @@ -232,18 +291,21 @@ static void clearoutscreen(void) { static void clearoutfullscreen(void) { RECT base; +const RECT *scrn; base.left = 0; base.top = 0; base.right = ddraw.width; base.bottom = ddraw.height; if (GetWindowLong(hWndMain, EXTGWL_HMENU)) { + scrn = &ddraw.scrn; base.top = 0; } else { + scrn = &ddraw.scrnclip; base.top = ddraw.menusize; } - clearoutofrect(&ddraw.scrn, &base); + clearoutofrect(scrn, &base); #if defined(SUPPORT_DCLOCK) DispClock::GetInstance()->Redraw(); #endif // defined(SUPPORT_DCLOCK) @@ -336,6 +398,7 @@ BRESULT scrnmng_create(UINT8 scrnmode) { LPDIRECTDRAW2 ddraw2; DDSURFACEDESC ddsd; DDPIXELFORMAT ddpf; + int width; int height; UINT bitcolor; @@ -373,13 +436,30 @@ BRESULT scrnmng_create(UINT8 scrnmode) { #endif // defined(SUPPORT_DCLOCK) ddraw2->SetCooperativeLevel(hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + width = SURFACE_WIDTH; height = 480; - bitcolor = 8; - if (scrnmode & (SCRNMODE_SYSHIGHCOLOR | SCRNMODE_COREHIGHCOLOR)) { - bitcolor = 16; + bitcolor = xmiloscfg.fscrnbpp; + const UINT8 fscrnmod = xmiloscfg.fscrnmod; + if (fscrnmod & (FSCRNMOD_SAMERES | FSCRNMOD_SAMEBPP)) + { + DEVMODE devmode; + if (EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, &devmode)) + { + if (fscrnmod & FSCRNMOD_SAMERES) + { + width = devmode.dmPelsWidth; + height = devmode.dmPelsHeight; + } + if (fscrnmod & FSCRNMOD_SAMEBPP) + { + bitcolor = devmode.dmBitsPerPel; + } + } } - if (ddraw2->SetDisplayMode(SURFACE_WIDTH, height, - bitcolor, 0, 0) != DD_OK) { + if (bitcolor == 0) { + bitcolor = (scrnmode & (SCRNMODE_SYSHIGHCOLOR | SCRNMODE_COREHIGHCOLOR)) ? 16 : 8; + } + if (ddraw2->SetDisplayMode(width, height, bitcolor, 0, 0) != DD_OK) { goto scre_err; } ddraw2->CreateClipper(0, &ddraw.clipper, NULL); @@ -405,7 +485,7 @@ BRESULT scrnmng_create(UINT8 scrnmode) { ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = SURFACE_WIDTH; - ddsd.dwHeight = height; + ddsd.dwHeight = SURFACE_HEIGHT; if (ddraw2->CreateSurface(&ddsd, &ddraw.backsurf, NULL) != DD_OK) { goto scre_err; } @@ -463,6 +543,7 @@ BRESULT scrnmng_create(UINT8 scrnmode) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = SURFACE_WIDTH; ddsd.dwHeight = SURFACE_HEIGHT; + width = SURFACE_WIDTH; height = SURFACE_HEIGHT; if (ddraw2->CreateSurface(&ddsd, &ddraw.backsurf, NULL) != DD_OK) { @@ -486,7 +567,7 @@ BRESULT scrnmng_create(UINT8 scrnmode) { scrnmng.bpp = (UINT8)bitcolor; scrnsurf.bpp = bitcolor; ddraw.scrnmode = scrnmode; - ddraw.width = SURFACE_WIDTH; + ddraw.width = width; ddraw.height = height; ddraw.cliping = 0; renewalclientsize(FALSE); @@ -661,6 +742,8 @@ void scrnmng_update(void) { POINT clip; RECT dst; + RECT *rect; + RECT *scrn; HRESULT r; if (scrnmng.palchanged) { @@ -673,7 +756,22 @@ void scrnmng_update(void) { scrnmng.allflash = 0; clearoutfullscreen(); } - dst = ddraw.scrn; + if (GetWindowLong(hWndMain, EXTGWL_HMENU)) { + rect = &ddraw.rect; + scrn = &ddraw.scrn; + } + else { + rect = &ddraw.rectclip; + scrn = &ddraw.scrnclip; + } + r = ddraw.primsurf->Blt(scrn, ddraw.backsurf, rect, + DDBLT_WAIT, NULL); + if (r == DDERR_SURFACELOST) { + ddraw.backsurf->Restore(); + ddraw.primsurf->Restore(); + ddraw.primsurf->Blt(scrn, ddraw.backsurf, rect, + DDBLT_WAIT, NULL); + } } else { if (scrnmng.allflash) { @@ -687,14 +785,14 @@ void scrnmng_update(void) { dst.top = clip.y + ddraw.scrn.top; dst.right = clip.x + ddraw.scrn.right; dst.bottom = clip.y + ddraw.scrn.bottom; - } - r = ddraw.primsurf->Blt(&dst, ddraw.backsurf, &ddraw.rect, - DDBLT_WAIT, NULL); - if (r == DDERR_SURFACELOST) { - ddraw.backsurf->Restore(); - ddraw.primsurf->Restore(); - ddraw.primsurf->Blt(&dst, ddraw.backsurf, &ddraw.rect, + r = ddraw.primsurf->Blt(&dst, ddraw.backsurf, &ddraw.rect, + DDBLT_WAIT, NULL); + if (r == DDERR_SURFACELOST) { + ddraw.backsurf->Restore(); + ddraw.primsurf->Restore(); + ddraw.primsurf->Blt(&dst, ddraw.backsurf, &ddraw.rect, DDBLT_WAIT, NULL); + } } } } @@ -730,7 +828,7 @@ void scrnmng_dispclock(void) DispClock::GetInstance()->Draw(scrnmng.bpp, dest.lpSurface, dest.lPitch); ddraw.clocksurf->Unlock(NULL); } - if (ddraw.primsurf->BltFast(640 - DCLOCK_WIDTH - 4, + if (ddraw.primsurf->BltFast(ddraw.width - DCLOCK_WIDTH - 4, ddraw.height - DCLOCK_HEIGHT, ddraw.clocksurf, const_cast(&rectclk), DDBLTFAST_WAIT) == DDERR_SURFACELOST) diff --git a/win9x/scrnmng.h b/win9x/scrnmng.h index 947f886..3b0ad25 100644 --- a/win9x/scrnmng.h +++ b/win9x/scrnmng.h @@ -31,6 +31,16 @@ enum { SCRNFLAG_ENABLE = 0x80 }; +enum { + FSCRNMOD_NORESIZE = 0x00, + FSCRNMOD_ASPECTFIX8 = 0x01, + FSCRNMOD_ASPECTFIX = 0x02, + FSCRNMOD_LARGE = 0x03, + FSCRNMOD_ASPECTMASK = 0x03, + FSCRNMOD_SAMERES = 0x04, + FSCRNMOD_SAMEBPP = 0x08 +}; + typedef struct { UINT8 flag; UINT8 bpp; diff --git a/win9x/xmil.cpp b/win9x/xmil.cpp index 81c67e5..0bcc456 100644 --- a/win9x/xmil.cpp +++ b/win9x/xmil.cpp @@ -57,6 +57,8 @@ static const OEMCHAR szClassName[] = OEMTEXT("Xmil-MainWindow"); #if defined(SUPPORT_DCLOCK) 0, 0, 0xffffff, 0xffbf6a, #endif // defined(SUPPORT_DCLOCK) + 0, + FSCRNMOD_SAMEBPP | FSCRNMOD_SAMERES | FSCRNMOD_ASPECTFIX8 }; OEMCHAR szProgName[] = OEMTEXT("X millennium ねこちゅ〜ん"); diff --git a/win9x/xmil.dsp b/win9x/xmil.dsp index a5c520c..99d25ae 100644 --- a/win9x/xmil.dsp +++ b/win9x/xmil.dsp @@ -553,6 +553,14 @@ SOURCE=.\dialog\d_sound.h # End Source File # Begin Source File +SOURCE=.\dialog\dialogs.cpp +# End Source File +# Begin Source File + +SOURCE=.\dialog\dialogs.h +# End Source File +# Begin Source File + SOURCE=.\DIALOG\EXTCLASS.CPP # End Source File # End Group diff --git a/win9x/xmil.h b/win9x/xmil.h index f94b162..c715c8a 100644 --- a/win9x/xmil.h +++ b/win9x/xmil.h @@ -28,6 +28,9 @@ typedef struct { UINT32 clockcolor1; UINT32 clockcolor2; #endif // defined(SUPPORT_DCLOCK) + + UINT8 fscrnbpp; + UINT8 fscrnmod; } XMILOSCFG; diff --git a/win9x/xmil.rc b/win9x/xmil.rc index 1ffc0fe..ca2116f 100644 --- a/win9x/xmil.rc +++ b/win9x/xmil.rc @@ -283,6 +283,21 @@ BEGIN RTEXT "",IDC_LIGHTSTR,144,22,20,10,SS_SUNKEN END +IDD_SCROPT_FULLSCREEN DIALOG DISCARDABLE 0, 0, 172, 96 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "FullScreen" +FONT 9, "MS Pゴシック" +BEGIN + CONTROL "No change screen &colors",IDC_FULLSCREEN_SAMEBPP,"Button", + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,8,8,156,10 + CONTROL "No change screen &resolution",IDC_FULLSCREEN_SAMERES, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,8,24, + 156,10 + LTEXT "&Zoom",IDC_STATIC,8,45,22,8 + COMBOBOX IDC_FULLSCREEN_ZOOM,40,42,96,80,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_GROUP | WS_TABSTOP +END + ///////////////////////////////////////////////////////////////////////////// // @@ -395,6 +410,10 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_SCREENOPTION "Screen option" + IDS_ZOOM_NONE "None" + IDS_ZOOM_FIXEDASPECT "Fixed aspect" + IDS_ZOOM_ADJUSTASPECT "Adjust aspect" + IDS_ZOOM_FULL "Full" END STRINGTABLE DISCARDABLE