2021-01-17 03:17:58 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* *
|
|
|
|
* Project64 - A Nintendo 64 emulator. *
|
|
|
|
* http://www.pj64-emu.com/ *
|
|
|
|
* Copyright (C) 2012 Project64. All rights reserved. *
|
|
|
|
* *
|
|
|
|
* License: *
|
|
|
|
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
|
|
|
* *
|
|
|
|
****************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <Project64\UserInterface\EnhancementUI.h>
|
|
|
|
#include <Project64-core\N64System\Enhancement\Enhancements.h>
|
|
|
|
|
|
|
|
class CEditEnhancement :
|
|
|
|
public CDialogImpl < CEditEnhancement >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
BEGIN_MSG_MAP_EX(CEditEnhancement)
|
|
|
|
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
|
|
|
COMMAND_HANDLER_EX(IDC_GAMESHARK, BN_CLICKED, OnGamesharkBtn)
|
|
|
|
COMMAND_ID_HANDLER(IDC_BTN_GAMESHARK, OnEditGameshark)
|
|
|
|
COMMAND_ID_HANDLER(IDOK, OnOkCmd)
|
|
|
|
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
|
|
|
|
END_MSG_MAP()
|
|
|
|
|
|
|
|
enum { IDD = IDD_Enhancement_Edit };
|
|
|
|
|
|
|
|
CEditEnhancement(CEnhancementUI & EnhancementUI, CEnhancement * Enhancement);
|
|
|
|
|
|
|
|
private:
|
|
|
|
CEditEnhancement(void);
|
|
|
|
CEditEnhancement(const CEditEnhancement&);
|
|
|
|
CEditEnhancement& operator=(const CEditEnhancement&);
|
|
|
|
|
|
|
|
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
|
|
|
LRESULT OnGamesharkBtn(UINT Code, int id, HWND ctl);
|
|
|
|
LRESULT OnEditGameshark(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
|
|
LRESULT OnOkCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
|
|
LRESULT OnCloseCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
|
|
|
|
|
|
CEnhancementUI & m_EnhancementUI;
|
|
|
|
CEnhancement::CodeEntries m_Entries;
|
2021-02-11 11:26:09 +00:00
|
|
|
CEnhancement::PluginList m_PluginList;
|
2021-01-17 03:17:58 +00:00
|
|
|
CEnhancement * m_EditEnhancement;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CEditGS :
|
2021-02-11 11:26:09 +00:00
|
|
|
public CDialogImpl<CEditGS>
|
2021-01-17 03:17:58 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
BEGIN_MSG_MAP_EX(CEditGS)
|
|
|
|
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
|
|
|
COMMAND_HANDLER(IDC_CHEAT_CODES, EN_CHANGE, OnCheatChanged)
|
2021-02-11 11:26:09 +00:00
|
|
|
COMMAND_HANDLER_EX(IDC_CHK_LIMIT_PLUGINS, BN_CLICKED, OnPluginBtn)
|
|
|
|
COMMAND_ID_HANDLER(IDC_BTN_PLUGIN, OnEditPlugins)
|
2021-01-17 03:17:58 +00:00
|
|
|
COMMAND_ID_HANDLER(IDOK, OnOkCmd)
|
|
|
|
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
|
|
|
|
END_MSG_MAP()
|
|
|
|
|
|
|
|
enum { IDD = IDD_Enhancement_GS };
|
|
|
|
|
2021-02-11 11:26:09 +00:00
|
|
|
CEditGS(CEnhancement::CodeEntries & Entries, CEnhancement::PluginList & PluginList);
|
2021-01-17 03:17:58 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
CEditGS();
|
|
|
|
CEditGS(const CEditGS&);
|
|
|
|
CEditGS& operator=(const CEditGS&);
|
|
|
|
|
|
|
|
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
|
2021-02-11 11:26:09 +00:00
|
|
|
LRESULT OnPluginBtn(UINT Code, int id, HWND ctl);
|
|
|
|
LRESULT OnEditPlugins(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
2021-01-17 03:17:58 +00:00
|
|
|
LRESULT OnCloseCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL & bHandled);
|
|
|
|
LRESULT OnOkCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL & bHandled);
|
|
|
|
LRESULT OnCheatChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL & bHandled);
|
|
|
|
|
|
|
|
bool CheatCode(CEnhancement::CodeEntries & Entries);
|
|
|
|
|
|
|
|
CEnhancement::CodeEntries & m_Entries;
|
2021-02-11 11:26:09 +00:00
|
|
|
CEnhancement::PluginList & m_PluginList;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CEditPluginList :
|
|
|
|
public CDialogImpl<CEditPluginList>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
BEGIN_MSG_MAP_EX(CEditPluginList)
|
|
|
|
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
2021-02-16 23:54:17 +00:00
|
|
|
COMMAND_ID_HANDLER(IDC_ADD, OnAddBtn)
|
|
|
|
COMMAND_ID_HANDLER(IDC_REMOVE, OnRemoveBtn)
|
2021-02-11 11:26:09 +00:00
|
|
|
COMMAND_ID_HANDLER(IDOK, OnOkCmd)
|
|
|
|
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
|
|
|
|
END_MSG_MAP()
|
|
|
|
|
|
|
|
enum { IDD = IDD_Enhancement_Plugins };
|
|
|
|
|
|
|
|
CEditPluginList(CEnhancement::PluginList & List);
|
|
|
|
|
|
|
|
private:
|
|
|
|
CEditPluginList();
|
|
|
|
CEditPluginList(const CEditPluginList&);
|
|
|
|
CEditPluginList& operator=(const CEditPluginList&);
|
|
|
|
|
|
|
|
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
|
|
|
|
LRESULT OnAddBtn(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
|
|
LRESULT OnRemoveBtn(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
|
|
LRESULT OnCloseCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL & bHandled);
|
|
|
|
LRESULT OnOkCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL & bHandled);
|
|
|
|
|
|
|
|
CListBox m_PluginListBox;
|
|
|
|
CEnhancement::PluginList & m_PluginList;
|
2021-01-17 03:17:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
CEnhancementUI::CEnhancementUI(void) :
|
2021-02-02 03:25:28 +00:00
|
|
|
m_hSelectedItem(NULL),
|
|
|
|
m_bModal(false)
|
2021-01-17 03:17:58 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void CEnhancementUI::Display(HWND hParent, bool BlockExecution)
|
|
|
|
{
|
|
|
|
if (g_BaseSystem)
|
|
|
|
{
|
|
|
|
g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_Enhancement);
|
|
|
|
}
|
|
|
|
if (BlockExecution)
|
|
|
|
{
|
|
|
|
m_bModal = true;
|
|
|
|
DoModal(hParent);
|
|
|
|
}
|
|
|
|
else if (m_hWnd != NULL)
|
|
|
|
{
|
|
|
|
SetFocus();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_bModal = false;
|
|
|
|
Create(hParent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEnhancementUI::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
2021-02-02 02:52:47 +00:00
|
|
|
SetWindowText(wGS(ENHANCEMENT_TITLE).c_str());
|
2021-01-17 03:17:58 +00:00
|
|
|
|
|
|
|
m_TreeList.Attach(GetDlgItem(IDC_ENHANCEMENTLIST));
|
|
|
|
LONG Style = m_TreeList.GetWindowLong(GWL_STYLE);
|
|
|
|
m_TreeList.SetWindowLong(GWL_STYLE, TVS_CHECKBOXES | TVS_SHOWSELALWAYS | Style);
|
|
|
|
|
|
|
|
HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR | ILC_MASK, 40, 40);
|
|
|
|
HBITMAP hBmp = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_TRI_STATE));
|
|
|
|
ImageList_AddMasked(hImageList, hBmp, RGB(255, 0, 255));
|
|
|
|
DeleteObject(hBmp);
|
|
|
|
m_TreeList.SetImageList(hImageList, TVSIL_STATE);
|
|
|
|
|
|
|
|
m_Enhancements = g_Enhancements->Enhancements();
|
2021-02-02 02:52:47 +00:00
|
|
|
|
|
|
|
CRect rcDlg, rcParent;
|
|
|
|
GetWindowRect(&rcDlg);
|
|
|
|
GetParent().GetWindowRect(&rcParent);
|
|
|
|
int32_t DlgWidth = rcDlg.Width();
|
|
|
|
int32_t DlgHeight = rcDlg.Height();
|
|
|
|
int32_t X = (((rcParent.Width()) - DlgWidth) / 2) + rcParent.left;
|
|
|
|
int32_t Y = (((rcParent.Height()) - DlgHeight) / 2) + rcParent.top;
|
|
|
|
SetWindowPos(NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
|
|
|
|
|
2021-01-17 03:17:58 +00:00
|
|
|
RefreshList();
|
2021-02-02 02:52:47 +00:00
|
|
|
ShowWindow(SW_SHOW);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEnhancementUI::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL & /*bHandled*/)
|
|
|
|
{
|
|
|
|
m_TreeList.Detach();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEnhancementUI::OnCloseCmd(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
if (m_bModal)
|
|
|
|
{
|
|
|
|
EndDialog(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DestroyWindow();
|
|
|
|
}
|
2021-01-17 03:17:58 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-02-02 02:52:47 +00:00
|
|
|
LRESULT CEnhancementUI::OnEditEnhancement(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
2021-01-17 03:17:58 +00:00
|
|
|
{
|
2021-02-02 02:52:47 +00:00
|
|
|
TVITEM item = { 0 };
|
|
|
|
item.mask = TVIF_PARAM;
|
|
|
|
item.hItem = m_hSelectedItem;
|
|
|
|
if (!m_TreeList.GetItem(&item) || item.lParam == NULL)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CEditEnhancement(*this, (CEnhancement *)item.lParam).DoModal(m_hWnd);
|
2021-01-17 03:17:58 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEnhancementUI::OnAddEnhancement(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
CEditEnhancement(*this, nullptr).DoModal(m_hWnd);
|
|
|
|
RefreshList();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-02-02 02:52:47 +00:00
|
|
|
LRESULT CEnhancementUI::OnEnhancementListClicked(NMHDR* lpnmh)
|
|
|
|
{
|
|
|
|
uint32_t dwpos = GetMessagePos();
|
|
|
|
TVHITTESTINFO ht = { 0 };
|
|
|
|
ht.pt.x = GET_X_LPARAM(dwpos);
|
|
|
|
ht.pt.y = GET_Y_LPARAM(dwpos);
|
|
|
|
::MapWindowPoints(HWND_DESKTOP, lpnmh->hwndFrom, &ht.pt, 1);
|
|
|
|
|
|
|
|
TreeView_HitTest(lpnmh->hwndFrom, &ht);
|
|
|
|
|
|
|
|
if (TVHT_ONITEMSTATEICON & ht.flags)
|
|
|
|
{
|
|
|
|
switch (TV_GetCheckState(ht.hItem))
|
|
|
|
{
|
|
|
|
case TV_STATE_CLEAR:
|
|
|
|
case TV_STATE_INDETERMINATE:
|
|
|
|
TV_SetCheckState(ht.hItem, TV_STATE_CHECKED);
|
|
|
|
ChangeChildrenStatus(ht.hItem, true);
|
|
|
|
CheckParentStatus(m_TreeList.GetParentItem(ht.hItem));
|
|
|
|
break;
|
|
|
|
case TV_STATE_CHECKED:
|
|
|
|
TV_SetCheckState(ht.hItem, TV_STATE_CLEAR);
|
|
|
|
ChangeChildrenStatus(ht.hItem, false);
|
|
|
|
CheckParentStatus(m_TreeList.GetParentItem(ht.hItem));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (TV_GetCheckState(ht.hItem))
|
|
|
|
{
|
|
|
|
case TV_STATE_CHECKED: TV_SetCheckState(ht.hItem, TV_STATE_INDETERMINATE); break;
|
|
|
|
case TV_STATE_CLEAR: TV_SetCheckState(ht.hItem, TV_STATE_CHECKED); break;
|
|
|
|
case TV_STATE_INDETERMINATE: TV_SetCheckState(ht.hItem, TV_STATE_CLEAR); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_Enhancements != nullptr)
|
|
|
|
{
|
|
|
|
g_Enhancements->UpdateCheats();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-01-17 03:17:58 +00:00
|
|
|
LRESULT CEnhancementUI::OnEnhancementListRClicked(NMHDR* pNMHDR)
|
|
|
|
{
|
|
|
|
TVHITTESTINFO ht = { 0 };
|
|
|
|
uint32_t dwpos = GetMessagePos();
|
|
|
|
ht.pt.x = GET_X_LPARAM(dwpos);
|
|
|
|
ht.pt.y = GET_Y_LPARAM(dwpos);
|
|
|
|
::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &ht.pt, 1);
|
|
|
|
|
|
|
|
TreeView_HitTest(pNMHDR->hwndFrom, &ht);
|
|
|
|
m_hSelectedItem = ht.hItem;
|
|
|
|
|
|
|
|
POINT Mouse;
|
|
|
|
GetCursorPos(&Mouse);
|
|
|
|
HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_ENHANCEMENT_MENU));
|
|
|
|
HMENU hPopupMenu = GetSubMenu(hMenu, 0);
|
|
|
|
|
|
|
|
if (m_hSelectedItem == NULL)
|
|
|
|
{
|
|
|
|
RemoveMenu(hPopupMenu, 3, MF_BYPOSITION);
|
|
|
|
RemoveMenu(hPopupMenu, 2, MF_BYPOSITION);
|
|
|
|
RemoveMenu(hPopupMenu, 1, MF_BYPOSITION);
|
|
|
|
}
|
|
|
|
|
|
|
|
TrackPopupMenu(hPopupMenu, 0, Mouse.x, Mouse.y, 0, m_hWnd, NULL);
|
|
|
|
DestroyMenu(hMenu);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEnhancementUI::OnEnhancementListDClicked(NMHDR* pNMHDR)
|
|
|
|
{
|
|
|
|
uint32_t dwpos = GetMessagePos();
|
|
|
|
TVHITTESTINFO ht = { 0 };
|
|
|
|
ht.pt.x = GET_X_LPARAM(dwpos);
|
|
|
|
ht.pt.y = GET_Y_LPARAM(dwpos);
|
|
|
|
::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &ht.pt, 1);
|
|
|
|
|
|
|
|
TreeView_HitTest(pNMHDR->hwndFrom, &ht);
|
|
|
|
|
|
|
|
if ((ht.flags & TVHT_ONITEMLABEL) == 0 || ht.hItem == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
TVITEM item = { 0 };
|
|
|
|
item.mask = TVIF_PARAM;
|
|
|
|
item.hItem = (HTREEITEM)ht.hItem;
|
|
|
|
if (!m_TreeList.GetItem(&item) || item.lParam == NULL)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CEditEnhancement(*this, (CEnhancement *)item.lParam).DoModal(m_hWnd);
|
|
|
|
RefreshList();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CEnhancementUI::AddCodeLayers(LPARAM Enhancement, const std::wstring & Name, HTREEITEM hParent, bool Active)
|
|
|
|
{
|
|
|
|
TV_INSERTSTRUCT tv;
|
|
|
|
|
|
|
|
wchar_t Text[500], Item[500];
|
|
|
|
if (Name.length() > ((sizeof(Text) / sizeof(Text[0])) - 5)) { g_Notify->BreakPoint(__FILE__, __LINE__); }
|
|
|
|
wcscpy(Text, Name.c_str());
|
|
|
|
if (wcschr(Text, L'\\') > 0) { *wcschr(Text, L'\\') = 0; }
|
|
|
|
|
|
|
|
tv.item.mask = TVIF_TEXT;
|
|
|
|
tv.item.pszText = Item;
|
|
|
|
tv.item.cchTextMax = sizeof(Item);
|
|
|
|
tv.item.hItem = m_TreeList.GetChildItem(hParent);
|
|
|
|
while (tv.item.hItem)
|
|
|
|
{
|
|
|
|
m_TreeList.GetItem(&tv.item);
|
|
|
|
if (wcscmp(Text, Item) == 0)
|
|
|
|
{
|
|
|
|
TV_CHECK_STATE State = TV_GetCheckState(tv.item.hItem);
|
|
|
|
if ((Active && State == TV_STATE_CLEAR) || (!Active && State == TV_STATE_CHECKED))
|
|
|
|
{
|
|
|
|
TV_SetCheckState(tv.item.hItem, TV_STATE_INDETERMINATE);
|
|
|
|
}
|
|
|
|
size_t StartPos = wcslen(Text) + 1;
|
|
|
|
std::wstring TempCheatName;
|
|
|
|
if (StartPos < Name.length())
|
|
|
|
{
|
|
|
|
TempCheatName = Name.substr(StartPos);
|
|
|
|
}
|
|
|
|
AddCodeLayers(Enhancement, TempCheatName, tv.item.hItem, Active);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
tv.item.hItem = m_TreeList.GetNextSiblingItem(tv.item.hItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
tv.hInsertAfter = TVI_SORT;
|
|
|
|
tv.item.mask = TVIF_TEXT | TVIF_PARAM;
|
|
|
|
tv.item.pszText = Text;
|
|
|
|
tv.item.lParam = Enhancement;
|
|
|
|
tv.hParent = hParent;
|
|
|
|
hParent = m_TreeList.InsertItem(&tv);
|
|
|
|
TV_SetCheckState(hParent, Active ? TV_STATE_CHECKED : TV_STATE_CLEAR);
|
|
|
|
|
|
|
|
if (wcscmp(Text, Name.c_str()) == 0) { return; }
|
|
|
|
AddCodeLayers(Enhancement, Name.substr(wcslen(Text) + 1), hParent, Active);
|
|
|
|
}
|
|
|
|
|
2021-02-02 02:52:47 +00:00
|
|
|
void CEnhancementUI::ChangeChildrenStatus(HTREEITEM hParent, bool Checked)
|
|
|
|
{
|
|
|
|
HTREEITEM hItem = m_TreeList.GetChildItem(hParent);;
|
|
|
|
if (hItem == NULL)
|
|
|
|
{
|
|
|
|
if (hParent == TVI_ROOT) { return; }
|
|
|
|
|
|
|
|
TVITEM item = { 0 };
|
|
|
|
item.mask = TVIF_PARAM;
|
|
|
|
item.hItem = hParent;
|
|
|
|
m_TreeList.GetItem(&item);
|
|
|
|
if (item.lParam == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
CEnhancement * Enhancement = (CEnhancement *)item.lParam;
|
|
|
|
if (Checked && Enhancement->CodeOptionSize() != 0 && Enhancement->GetOptions().size() > 0 && !Enhancement->OptionSelected())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TV_SetCheckState(hParent, Checked ? TV_STATE_CHECKED : TV_STATE_CLEAR);
|
|
|
|
Enhancement->SetActive(Checked);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
TV_CHECK_STATE state = TV_STATE_UNKNOWN;
|
|
|
|
while (hItem != NULL)
|
|
|
|
{
|
|
|
|
TV_CHECK_STATE ChildState = TV_GetCheckState(hItem);
|
|
|
|
if ((ChildState != TV_STATE_CHECKED || !Checked) &&
|
|
|
|
(ChildState != TV_STATE_CLEAR || Checked))
|
|
|
|
{
|
|
|
|
ChangeChildrenStatus(hItem, Checked);
|
|
|
|
}
|
|
|
|
ChildState = TV_GetCheckState(hItem);
|
|
|
|
if (state == TV_STATE_UNKNOWN) { state = ChildState; }
|
|
|
|
if (state != ChildState) { state = TV_STATE_INDETERMINATE; }
|
|
|
|
hItem = m_TreeList.GetNextSiblingItem(hItem);
|
|
|
|
}
|
|
|
|
if (state != TV_STATE_UNKNOWN)
|
|
|
|
{
|
|
|
|
TV_SetCheckState(hParent, state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CEnhancementUI::CheckParentStatus(HTREEITEM hParent)
|
|
|
|
{
|
|
|
|
if (hParent == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
HTREEITEM hItem = m_TreeList.GetChildItem(hParent);
|
|
|
|
TV_CHECK_STATE InitialState = TV_GetCheckState(hParent);
|
|
|
|
TV_CHECK_STATE CurrentState = TV_GetCheckState(hItem);
|
|
|
|
while (hItem != NULL)
|
|
|
|
{
|
|
|
|
if (TV_GetCheckState(hItem) != CurrentState)
|
|
|
|
{
|
|
|
|
CurrentState = TV_STATE_INDETERMINATE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
hItem = m_TreeList.GetNextSiblingItem(hItem);
|
|
|
|
}
|
|
|
|
TV_SetCheckState(hParent, CurrentState);
|
|
|
|
if (InitialState != CurrentState)
|
|
|
|
{
|
|
|
|
CheckParentStatus(m_TreeList.GetParentItem(hParent));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-17 03:17:58 +00:00
|
|
|
void CEnhancementUI::RefreshList()
|
|
|
|
{
|
|
|
|
m_TreeList.DeleteAllItems();
|
|
|
|
for (CEnhancementList::iterator itr = m_Enhancements.begin(); itr != m_Enhancements.end(); itr++)
|
|
|
|
{
|
|
|
|
std::string Name = itr->second.GetNameAndExtension();
|
|
|
|
if (Name.length() == 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
AddCodeLayers((LPARAM)&itr->second, stdstr(Name).ToUTF16(), TVI_ROOT, itr->second.Active());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CEnhancementUI::TV_CHECK_STATE CEnhancementUI::TV_GetCheckState(HTREEITEM hItem)
|
|
|
|
{
|
|
|
|
TVITEM tvItem = { 0 };
|
|
|
|
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
|
|
|
|
tvItem.hItem = hItem;
|
|
|
|
tvItem.stateMask = TVIS_STATEIMAGEMASK;
|
|
|
|
|
|
|
|
m_TreeList.GetItem(&tvItem);
|
|
|
|
|
|
|
|
switch (tvItem.state >> 12)
|
|
|
|
{
|
|
|
|
case 1: return TV_STATE_CHECKED;
|
|
|
|
case 2: return TV_STATE_CLEAR;
|
|
|
|
case 3: return TV_STATE_INDETERMINATE;
|
|
|
|
}
|
|
|
|
return TV_STATE_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CEnhancementUI::TV_SetCheckState(HTREEITEM hItem, TV_CHECK_STATE state)
|
|
|
|
{
|
|
|
|
TVITEM tvItem = { 0 };
|
|
|
|
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
|
|
|
|
tvItem.hItem = (HTREEITEM)hItem;
|
|
|
|
tvItem.stateMask = TVIS_STATEIMAGEMASK;
|
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case TV_STATE_CHECKED: tvItem.state = INDEXTOSTATEIMAGEMASK(1); break;
|
|
|
|
case TV_STATE_CLEAR: tvItem.state = INDEXTOSTATEIMAGEMASK(2); break;
|
|
|
|
case TV_STATE_INDETERMINATE: tvItem.state = INDEXTOSTATEIMAGEMASK(3); break;
|
|
|
|
default: tvItem.state = INDEXTOSTATEIMAGEMASK(0); break;
|
|
|
|
}
|
|
|
|
return m_TreeList.SetItem(&tvItem) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CEditEnhancement::CEditEnhancement(CEnhancementUI & EnhancementUI, CEnhancement * Enhancement) :
|
|
|
|
m_EnhancementUI(EnhancementUI),
|
|
|
|
m_EditEnhancement(Enhancement)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditEnhancement::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
m_Entries = m_EditEnhancement != nullptr ? m_EditEnhancement->GetEntries() : CEnhancement::CodeEntries();
|
2021-02-11 11:26:09 +00:00
|
|
|
m_PluginList = m_EditEnhancement != nullptr ? m_EditEnhancement->GetPluginList() : CEnhancement::PluginList();
|
2021-01-17 03:17:58 +00:00
|
|
|
GetDlgItem(IDC_OVERCLOCK).EnableWindow(false);
|
|
|
|
GetDlgItem(IDC_OVER_CLOCK_MODIFIER).EnableWindow(false);
|
|
|
|
GetDlgItem(IDC_CODE_NAME).SetWindowText(m_EditEnhancement != nullptr ? stdstr(m_EditEnhancement->GetName()).ToUTF16().c_str() : L"");
|
|
|
|
GetDlgItem(IDC_NOTES).SetWindowText(m_EditEnhancement != nullptr ? stdstr(m_EditEnhancement->GetNote()).ToUTF16().c_str() : L"");
|
|
|
|
CButton(GetDlgItem(IDC_AUTOON)).SetCheck(m_EditEnhancement != nullptr ? (m_EditEnhancement->GetOnByDefault() ? BST_CHECKED : BST_UNCHECKED) : BST_UNCHECKED);
|
|
|
|
CButton(GetDlgItem(IDC_GAMESHARK)).SetCheck(m_Entries.size() > 0 ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditEnhancement::OnGamesharkBtn(UINT /*Code*/, int /*id*/, HWND /*ctl*/)
|
|
|
|
{
|
|
|
|
CButton(GetDlgItem(IDC_GAMESHARK)).SetCheck(m_Entries.size() > 0 ? BST_CHECKED : BST_UNCHECKED);
|
2021-02-11 11:26:09 +00:00
|
|
|
CEditGS(m_Entries, m_PluginList).DoModal(m_hWnd);
|
2021-01-17 03:17:58 +00:00
|
|
|
CButton(GetDlgItem(IDC_GAMESHARK)).SetCheck(m_Entries.size() > 0 ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditEnhancement::OnEditGameshark(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
OnGamesharkBtn(0, 0, 0);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditEnhancement::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
EndDialog(wID);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditEnhancement::OnOkCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
CEnhancementList & Enhancements = m_EnhancementUI.m_Enhancements;
|
|
|
|
if (m_EditEnhancement != nullptr)
|
|
|
|
{
|
|
|
|
m_EditEnhancement->SetName(GetCWindowText(GetDlgItem(IDC_CODE_NAME)).c_str());
|
|
|
|
m_EditEnhancement->SetOnByDefault(CButton(GetDlgItem(IDC_AUTOON)).GetCheck() == BST_CHECKED);
|
|
|
|
m_EditEnhancement->SetEntries(m_Entries);
|
2021-02-11 11:26:09 +00:00
|
|
|
m_EditEnhancement->SetPluginList(m_PluginList);
|
2021-01-17 03:17:58 +00:00
|
|
|
m_EditEnhancement->SetNote(GetCWindowText(GetDlgItem(IDC_NOTES)).c_str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CEnhancement Enhancement("Enhancement");
|
|
|
|
Enhancement.SetName(GetCWindowText(GetDlgItem(IDC_CODE_NAME)).c_str());
|
|
|
|
Enhancement.SetOnByDefault(CButton(GetDlgItem(IDC_AUTOON)).GetCheck() == BST_CHECKED);
|
|
|
|
Enhancement.SetEntries(m_Entries);
|
2021-02-11 11:26:09 +00:00
|
|
|
Enhancement.SetPluginList(m_PluginList);
|
2021-01-17 03:17:58 +00:00
|
|
|
Enhancement.SetNote(GetCWindowText(GetDlgItem(IDC_NOTES)).c_str());
|
|
|
|
Enhancements.AddItem(Enhancement);
|
|
|
|
}
|
|
|
|
g_Enhancements->UpdateEnhancements(Enhancements);
|
|
|
|
m_EnhancementUI.RefreshList();
|
|
|
|
EndDialog(wID);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-11 11:26:09 +00:00
|
|
|
CEditGS::CEditGS(CEnhancement::CodeEntries & Entries, CEnhancement::PluginList & PluginList) :
|
|
|
|
m_Entries(Entries),
|
|
|
|
m_PluginList(PluginList)
|
2021-01-17 03:17:58 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditGS::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
stdstr Buffer;
|
|
|
|
for (size_t i = 0, n = m_Entries.size(); i < n; i++)
|
|
|
|
{
|
|
|
|
const CEnhancement::CodeEntry Entry = m_Entries[i];
|
|
|
|
if (!Buffer.empty())
|
|
|
|
{
|
|
|
|
Buffer.append("\r\n");
|
|
|
|
}
|
|
|
|
Buffer += stdstr_f("%08X %s", Entry.Command, Entry.Value.c_str());
|
|
|
|
}
|
|
|
|
CEdit CheatCodes(GetDlgItem(IDC_CHEAT_CODES));
|
|
|
|
CheatCodes.SetWindowText(Buffer.ToUTF16().c_str());
|
2021-02-11 11:26:09 +00:00
|
|
|
CButton(GetDlgItem(IDC_CHK_LIMIT_PLUGINS)).SetCheck(m_PluginList.size() > 0 ? BST_CHECKED : BST_UNCHECKED);
|
2021-01-17 03:17:58 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-02-11 11:26:09 +00:00
|
|
|
LRESULT CEditGS::OnPluginBtn(UINT /*Code*/, int /*id*/, HWND /*ctl*/)
|
|
|
|
{
|
|
|
|
CButton(GetDlgItem(IDC_CHK_LIMIT_PLUGINS)).SetCheck(m_PluginList.size() > 0 ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
CEditPluginList(m_PluginList).DoModal(m_hWnd);
|
|
|
|
CButton(GetDlgItem(IDC_CHK_LIMIT_PLUGINS)).SetCheck(m_PluginList.size() > 0 ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditGS::OnEditPlugins(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
OnPluginBtn(0, 0, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-01-17 03:17:58 +00:00
|
|
|
LRESULT CEditGS::OnCheatChanged(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
CEnhancement::CodeEntries Entries;
|
|
|
|
GetDlgItem(IDOK).EnableWindow(CheatCode(Entries));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditGS::OnOkCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
CEnhancement::CodeEntries Entries;
|
|
|
|
if (CheatCode(Entries))
|
|
|
|
{
|
|
|
|
m_Entries = Entries;
|
|
|
|
EndDialog(wID);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditGS::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
|
|
|
{
|
|
|
|
EndDialog(wID);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CEditGS::CheatCode(CEnhancement::CodeEntries & Entries)
|
|
|
|
{
|
|
|
|
Entries.clear();
|
|
|
|
|
|
|
|
bool ValidCode = true;
|
|
|
|
CEdit CheatCodes(GetDlgItem(IDC_CHEAT_CODES));
|
|
|
|
uint32_t numlines = CheatCodes.GetLineCount();
|
|
|
|
|
|
|
|
for (uint32_t line = 0; line < numlines; line++)
|
|
|
|
{
|
|
|
|
const char * formatnormal = "XXXXXXXX XXXX";
|
|
|
|
|
|
|
|
wchar_t wstr[128] = { 0 };
|
|
|
|
*(LPWORD)wstr = sizeof(wstr) / sizeof(wstr[0]);
|
|
|
|
uint32_t len = CheatCodes.GetLine(line, wstr);
|
|
|
|
wstr[len] = 0;
|
|
|
|
|
|
|
|
if (len <= 0) { continue; }
|
|
|
|
|
|
|
|
std::string str = stdstr().FromUTF16(wstr);
|
|
|
|
char tempformat[128] = { 0 };
|
|
|
|
for (uint32_t i = 0; i < sizeof(tempformat); i++)
|
|
|
|
{
|
|
|
|
if (isxdigit(str[i]))
|
|
|
|
{
|
|
|
|
tempformat[i] = 'X';
|
|
|
|
}
|
|
|
|
if (str[i] == ' ')
|
|
|
|
{
|
|
|
|
tempformat[i] = str[i];
|
|
|
|
}
|
|
|
|
if (str[i] == 0) { break; }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(tempformat, formatnormal) == 0)
|
|
|
|
{
|
|
|
|
CEnhancement::CodeEntry Entry;
|
|
|
|
Entry.Command = strtoul(str.c_str(), 0, 16);
|
|
|
|
const char * ReadPos = strchr(str.c_str(), ' ');
|
|
|
|
if (ReadPos != nullptr)
|
|
|
|
{
|
|
|
|
Entry.Value = ReadPos + 1;
|
|
|
|
Entries.push_back(Entry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ValidCode = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ValidCode = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ValidCode && Entries.size() > 0)
|
|
|
|
{
|
|
|
|
CEnhancement Item("");
|
|
|
|
Item.SetName("Test");
|
|
|
|
Item.SetEntries(Entries);
|
|
|
|
if (!Item.Valid() || Item.CodeOptionSize() != 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ValidCode;
|
|
|
|
}
|
2021-02-11 11:26:09 +00:00
|
|
|
|
|
|
|
CEditPluginList::CEditPluginList(CEnhancement::PluginList & List) :
|
|
|
|
m_PluginList(List)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditPluginList::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL & /*bHandled*/)
|
|
|
|
{
|
|
|
|
m_PluginListBox.Attach(GetDlgItem(IDC_PLUGIN_LIST));
|
|
|
|
for (size_t i = 0, n = m_PluginList.size(); i < n; i++)
|
|
|
|
{
|
|
|
|
m_PluginListBox.AddString(stdstr(m_PluginList[i]).ToUTF16().c_str());
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditPluginList::OnAddBtn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL & /*bHandled*/)
|
|
|
|
{
|
|
|
|
CWindow hEdit = GetDlgItem(IDC_ADD_EDIT);
|
|
|
|
stdstr PluginName = stdstr(GetCWindowText(hEdit)).Trim();
|
|
|
|
std::wstring wPluginName = PluginName.ToUTF16();
|
|
|
|
if (PluginName.empty())
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
for (int i = 0, n = m_PluginListBox.GetCount(); i < n; i++)
|
|
|
|
{
|
|
|
|
int nLen = m_PluginListBox.GetTextLen(i);
|
|
|
|
if (nLen == 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
std::wstring WindowText;
|
|
|
|
WindowText.resize(nLen + 1);
|
|
|
|
m_PluginListBox.GetText(i, (wchar_t *)WindowText.c_str());
|
|
|
|
if (strcmp(stdstr().FromUTF16(WindowText.c_str()).c_str(), PluginName.c_str()) == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hEdit.SetWindowText(L"");
|
|
|
|
m_PluginListBox.AddString(wPluginName.c_str());
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditPluginList::OnRemoveBtn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL & /*bHandled*/)
|
|
|
|
{
|
|
|
|
int index = m_PluginListBox.GetCurSel();
|
|
|
|
if (index >= 0)
|
|
|
|
{
|
|
|
|
m_PluginListBox.DeleteString(index);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditPluginList::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL & /*bHandled*/)
|
|
|
|
{
|
|
|
|
EndDialog(wID);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CEditPluginList::OnOkCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL & /*bHandled*/)
|
|
|
|
{
|
|
|
|
CEnhancement::PluginList PluginList;
|
|
|
|
for (int i = 0, n = m_PluginListBox.GetCount(); i < n; i++)
|
|
|
|
{
|
|
|
|
int nLen = m_PluginListBox.GetTextLen(i);
|
|
|
|
if (nLen == 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
std::wstring WindowText;
|
|
|
|
WindowText.resize(nLen + 1);
|
|
|
|
m_PluginListBox.GetText(i, (wchar_t *)WindowText.c_str());
|
|
|
|
|
|
|
|
PluginList.push_back(stdstr().FromUTF16(WindowText.c_str()));
|
|
|
|
}
|
|
|
|
m_PluginList = PluginList;
|
|
|
|
EndDialog(wID);
|
|
|
|
return 0;
|
|
|
|
}
|