Merge pull request #32 from owomomo/master

UI improvements and detail fixes
This commit is contained in:
zeromus 2019-03-18 00:10:06 -04:00 committed by GitHub
commit 320c868ebd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 3555 additions and 3352 deletions

View File

@ -60,26 +60,8 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p)
}
struct CHEATF {
struct CHEATF *next;
char *name;
uint16 addr;
uint8 val;
int compare; /* -1 for no compare. */
int type; /* 0 for replace, 1 for substitute(GG). */
int status;
};
typedef struct {
uint16 addr;
uint8 val;
int compare;
readfunc PrevRead;
} CHEATF_SUBFAST;
static CHEATF_SUBFAST SubCheats[256];
static int numsubcheats=0;
CHEATF_SUBFAST SubCheats[256];
int numsubcheats=0;
struct CHEATF *cheats=0,*cheatsl=0;

View File

@ -11,4 +11,21 @@ void FCEU_CheatSetByte(uint32 A, uint8 V);
extern int savecheats;
int FCEU_DisableAllCheats();
int FCEU_DisableAllCheats();
typedef struct {
uint16 addr;
uint8 val;
int compare;
readfunc PrevRead;
} CHEATF_SUBFAST;
struct CHEATF {
struct CHEATF *next;
char *name;
uint16 addr;
uint8 val;
int compare; /* -1 for no compare. */
int type; /* 0 for replace, 1 for substitute(GG). */
int status;
};

View File

@ -285,8 +285,6 @@ static BOOL CALLBACK ArchiveFileSelectorCallback(HWND hwndDlg, UINT uMsg, WPARAM
{
case WM_INITDIALOG:
{
// TODO: find a better way to do this.
archiveManuallyCanceled = false;
HWND hwndListbox = GetDlgItem(hwndDlg,IDC_LIST1);
for(uint32 i=0;i<currFileSelectorContext->size();i++)
{

View File

@ -9,6 +9,11 @@
#include "window.h"
#include "taseditor/taseditor_window.h"
// whitch column does the sort based on, the default status -1 is natrually not sorted (or sort by FCEUI_CommandTable)
static int mapInputSortCol = -1;
// whether it's asc or desc sorting, when sortCol is -1, this value has no effect
static bool mapInputSortAsc = true;
void KeyboardUpdateState(void); //mbg merge 7/17/06 yech had to add this
struct INPUTDLGTHREADARGS
@ -552,6 +557,30 @@ void PopulateMappingDisplay(HWND hwndDlg)
{
free(conflictTable);
}
if (mapInputSortCol != -1)
{
NMHDR hdr;
hdr.hwndFrom = hwndListView;
hdr.code = LVN_COLUMNCLICK;
NMLISTVIEW listView;
listView.hdr = hdr;
// when showing the conflict table, always sorted by "Input" column first,
// So the user can easily find out which are conflicting.
if (filter == EMUCMDTYPE_MAX + 3)
listView.iSubItem = 2;
// only one type is in the list, just sort with "Command" column
// "Unassigned" has no text in "Input", just sort with "Command" column
else if (filter > EMUCMDTYPE_MISC && filter < EMUCMDTYPE_MAX || filter == EMUCMDTYPE_MAX + 2)
listView.iSubItem = 1;
else
listView.iSubItem = mapInputSortCol;
int ret = SendMessage(hwndListView, LVM_SORTITEMS, (WPARAM)&listView, (LPARAM)MapInputItemSortFunc);
UpdateSortColumnIcon(hwndListView, mapInputSortCol, mapInputSortAsc);
}
}
/**
@ -712,12 +741,14 @@ BOOL CALLBACK MapInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
switch(LOWORD(wParam))
{
case IDOK:
UpdateMenuHotkeys();
EndDialog(hwndDlg, 1);
// Update TAS Editor's tooltips if it's opening.
extern TASEDITOR_WINDOW taseditorWindow;
if (taseditorWindow.hwndTASEditor)
taseditorWindow.updateTooltips();
EndDialog(hwndDlg, 1);
// main menu is always shown, so we only need to update it,
// the context menus are updated only when they are created
UpdateMenuHotkeys(FCEUMENU_MAIN);
return TRUE;
case BTN_CANCEL: // here true cause of ESC button handling as EXIT ;)
@ -746,23 +777,46 @@ BOOL CALLBACK MapInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
case LV_MAPPING:
if (lParam)
{
NMHDR* pnm = (NMHDR*)lParam;
if (pnm->code == LVN_ITEMACTIVATE)
NMLISTVIEW* lpListView = (NMLISTVIEW*)lParam;
UINT code = lpListView->hdr.code;
HWND hwndListView = lpListView->hdr.hwndFrom;
switch (code)
{
HWND hwndListView = GetDlgItem(hwndDlg, LV_MAPPING);
case LVN_ITEMACTIVATE:
AskForHotkey(hwndListView);
AskForHotkey(hwndListView);
// TODO: Only redraw if Conflicts filter
// is active.
PopulateMappingDisplay(hwndDlg);
break;
case LVN_COLUMNCLICK:
// Sort the items
if (mapInputSortCol != lpListView->iSubItem) {
mapInputSortCol= lpListView->iSubItem;
mapInputSortAsc = true;
}
else
mapInputSortAsc = !mapInputSortAsc;
// TODO: Only redraw if Conflicts filter
// is active.
PopulateMappingDisplay(hwndDlg);
int filter = (int)SendDlgItemMessage(hwndDlg, COMBO_FILTER, CB_GETCURSEL, 0, 0);
// when showing the conflict table, always sorted by "Input" column first,
// So the user can easily find out which are conflicting.
if (filter == EMUCMDTYPE_MAX + 3)
lpListView->iSubItem = 2;
// only one type is in the list, just sort with "Command" column
// "Unassigned" has no text in "Input", just sort with "Command" column
else if (filter > EMUCMDTYPE_MISC && filter < EMUCMDTYPE_MAX || filter == EMUCMDTYPE_MAX + 2)
lpListView->iSubItem = 1;
else
lpListView->iSubItem = mapInputSortCol;
int ret = SendMessage(hwndListView, LVM_SORTITEMS, (WPARAM)lpListView, (LPARAM)MapInputItemSortFunc);
UpdateSortColumnIcon(hwndListView, mapInputSortCol, mapInputSortAsc);
}
return TRUE;
}
break;
default:
break;
}
@ -792,3 +846,51 @@ void MapInput(void)
free(backupmapping);
}
static int CALLBACK MapInputItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort)
{
NMLISTVIEW* lpListView = (NMLISTVIEW*)lpSort;
HWND hwndListView = lpListView->hdr.hwndFrom;
LVFINDINFO info1, info2;
LVITEM item1, item2;
memset(&info1, 0, sizeof(LVFINDINFO));
memset(&info2, 0, sizeof(LVFINDINFO));
memset(&item1, 0, sizeof(LVITEM));
memset(&item2, 0, sizeof(LVITEM));
info1.flags = LVFI_PARAM;
info2.flags = LVFI_PARAM;
info1.lParam = lp1;
info2.lParam = lp2;
int index1 = SendMessage(hwndListView, LVM_FINDITEM, -1, (LPARAM)&info1);
int index2 = SendMessage(hwndListView, LVM_FINDITEM, -1, (LPARAM)&info2);
item1.pszText = new char[64];
item2.pszText = new char[64];
item1.cchTextMax = 64;
item2.cchTextMax = 64;
item1.iSubItem = lpListView->iSubItem;
item2.iSubItem = lpListView->iSubItem;
SendMessage(hwndListView, LVM_GETITEMTEXT, index1, (LPARAM)&item1);
SendMessage(hwndListView, LVM_GETITEMTEXT, index2, (LPARAM)&item2);
int ret = strcmp(item1.pszText, item2.pszText);
// "Type" and "Input" column can have repeated items, uses "Command" line for another sorting
if (ret == 0 && (lpListView->iSubItem == 0 || lpListView->iSubItem == 2))
{
item1.iSubItem = 1;
item2.iSubItem = 1;
SendMessage(hwndListView, LVM_GETITEMTEXT, index1, (LPARAM)&item1);
SendMessage(hwndListView, LVM_GETITEMTEXT, index2, (LPARAM)&item2);
ret = strcmp(item1.pszText, item2.pszText);
}
if (!mapInputSortAsc)
ret = -ret;
delete[] item1.pszText;
delete[] item2.pszText;
return ret;
}

View File

@ -1,4 +1,6 @@
#ifndef WIN_MAPINPUT_h
#define WIN_MAPINPUT_h
char* GetKeyComboName(int c);
static int CALLBACK MapInputItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort);
void UpdateSortColumnIcon(HWND hwndListView, int sortColumn, bool sortAsc);
#endif

View File

@ -478,9 +478,11 @@ BOOL CALLBACK NTViewCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
SelectObject (pDC, CreatePen (PS_SOLID, 2, RGB (255, 255, 255))) ;
CheckDlgButton(hwndDlg, IDC_NTVIEW_SHOW_SCROLL_LINES, BST_CHECKED);
CheckDlgButton(hwndDlg, IDC_NTVIEW_SHOW_ATTRIBUTES, BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_NTVIEW_HIDE_PALETTES, BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_NTVIEW_SHOW_SCROLL_LINES, scrolllines ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hwndDlg, IDC_NTVIEW_SCANLINE_TEXT), scrolllines);
EnableWindow(GetDlgItem(hwndDlg, IDC_NTVIEW_SCANLINE), scrolllines);
CheckDlgButton(hwndDlg, IDC_NTVIEW_SHOW_ATTRIBUTES, attview ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_NTVIEW_HIDE_PALETTES, hidepal ? BST_CHECKED : BST_UNCHECKED);
//clear cache
memset(palcache,0,32);

View File

@ -29,6 +29,7 @@
#include "common.h"
#include "fceu.h"
#include "../../debug.h"
#include "../../cheat.h"
#include "resource.h"
#include "ram_search.h"
@ -48,6 +49,17 @@
bool ShowROM = false;
// Too much work to do for resorting the values, and finding the biggest number
// by sorting in ram list doesn't help too much in usually use, so I gave it up.
// whitch column does the sort based on, the default status is 0 which means sorted by address
// static int ramSearchSortCol = 0;
// whether it's asc or desc sorting
// static bool ramSearchSortAsc = true;
// used for changing colors of cheated address.
extern int numsubcheats;
extern CHEATF_SUBFAST SubCheats[256];
bool IsHardwareAddressValid(HWAddressType address)
{
if (!GameInfo)
@ -73,6 +85,7 @@ struct MemoryRegion
unsigned int virtualIndex; // index into s_prevValues, s_curValues, and s_numChanges, valid after being initialized in ResetMemoryRegions()
unsigned int itemIndex; // index into listbox items, valid when s_itemIndicesInvalid is false
unsigned int cheatAffect; // how many bytes affected by the cheats. 0 indicates for free, max value is the size.
};
int MAX_RAM_SIZE = 0;
@ -169,6 +182,19 @@ void ResetMemoryRegions()
LeaveCriticalSection(&s_activeMemoryRegionsCS);
}
/* currently not used, only virtual region is to show the cheat status
void UpdateMemoryCheatStatus()
{
EnterCriticalSection(&s_activeMemoryRegionsCS);
for (MemoryList::iterator iter = s_activeMemoryRegions.begin(); iter != s_activeMemoryRegions.end(); ++iter)
{
MemoryRegion& region = *iter;
UpdateRegionCheatStatus(region);
}
LeaveCriticalSection(&s_activeMemoryRegionsCS);
}
*/
// eliminates a range of hardware addresses from the search results
// returns 2 if it changed the region and moved the iterator to another region
// returns 1 if it changed the region but didn't move the iterator
@ -249,7 +275,7 @@ void CalculateItemIndices(int itemSize)
int startSkipSize = ((unsigned int)(itemSize - (unsigned int)region.hardwareAddress)) % itemSize; // FIXME: is this still ok?
unsigned int start = startSkipSize;
unsigned int end = region.size;
for(unsigned int i = start; i < end; i += itemSize)
for (unsigned int i = start; i < end; i += itemSize)
s_itemIndexToRegionPointer[itemIndex++] = &region;
}
s_maxItemIndex = itemIndex;
@ -386,8 +412,8 @@ void ItemIndexToVirtualRegion(unsigned int itemIndex, MemoryRegion& virtualRegio
return;
}
const MemoryRegion* regionPtr = s_itemIndexToRegionPointer[itemIndex];
const MemoryRegion& region = *regionPtr;
MemoryRegion* regionPtr = s_itemIndexToRegionPointer[itemIndex];
MemoryRegion& region = *regionPtr;
int bytesWithinRegion = (itemIndex - region.itemIndex) * sizeof(stepType);
int startSkipSize = ((unsigned int)(sizeof(stepType) - region.hardwareAddress)) % sizeof(stepType);
@ -397,7 +423,11 @@ void ItemIndexToVirtualRegion(unsigned int itemIndex, MemoryRegion& virtualRegio
virtualRegion.hardwareAddress = region.hardwareAddress + bytesWithinRegion;
virtualRegion.virtualIndex = region.virtualIndex + bytesWithinRegion;
virtualRegion.itemIndex = itemIndex;
return;
region.cheatAffect = 0;
for (int i = 0; i < numsubcheats; i++)
if (SubCheats[i].addr >= region.hardwareAddress && SubCheats[i].addr < region.hardwareAddress + region.size)
++region.cheatAffect;
}
template<typename stepType, typename compareType>
@ -464,6 +494,13 @@ unsigned int GetHardwareAddressFromItemIndex(unsigned int itemIndex)
ItemIndexToVirtualRegion<stepType,compareType>(itemIndex, virtualRegion);
return virtualRegion.hardwareAddress;
}
template<typename stepType, typename compareType>
unsigned int GetCheatStatusFromItemIndex(unsigned int itemIndex)
{
MemoryRegion virtualRegion;
ItemIndexToVirtualRegion<stepType, compareType>(itemIndex, virtualRegion);
return virtualRegion.cheatAffect;
}
// this one might be unreliable, haven't used it much
template<typename stepType, typename compareType>
@ -987,6 +1024,7 @@ void soft_reset_address_info ()
}*/
s_prevValuesNeedUpdate = false;
ResetMemoryRegions();
// UpdateMemoryCheatStatus();
if(!RamSearchHWnd)
{
EnterCriticalSection(&s_activeMemoryRegionsCS);
@ -1015,6 +1053,7 @@ void reset_address_info ()
memcpy(s_prevValues, s_curValues, (sizeof(*s_prevValues)*(MAX_RAM_SIZE)));
s_prevValuesNeedUpdate = false;
ResetMemoryRegions();
// UpdateMemoryCheatStatus();
if(!RamSearchHWnd)
{
EnterCriticalSection(&s_activeMemoryRegionsCS);
@ -1374,7 +1413,6 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
RECT r2;
int dx1, dy1, dx2, dy2;
static int watchIndex=0;
switch(uMsg)
{
case WM_INITDIALOG: {
@ -1481,8 +1519,8 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
SendDlgItemMessage(hDlg,IDC_C_SEARCHROM,BM_SETCHECK,ShowROM?BST_CHECKED:BST_UNCHECKED,0);
//const char* names[5] = {"Address","Value","Previous","Changes","Notes"};
//int widths[5] = {62,64,64,55,55};
const char* names[] = {"Address","Value","Previous","Changes"};
int widths[4] = {68,76,76,68};
const char* names[5] = {"Addr.","Value","Previous","Changes","Cheats"};
int widths[5] = {48,80,80,66,52};
if (!ResultCount)
reset_address_info();
else
@ -1491,7 +1529,7 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
CompactAddrs();
}
void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidths);
init_list_box(GetDlgItem(hDlg,IDC_RAMLIST),names,4,widths);
init_list_box(GetDlgItem(hDlg,IDC_RAMLIST),names,5,widths);
//ListView_SetItemCount(GetDlgItem(hDlg,IDC_RAMLIST),ResultCount);
if (!noMisalign) SendDlgItemMessage(hDlg, IDC_MISALIGN, BM_SETCHECK, BST_CHECKED, 0);
//if (littleEndian) SendDlgItemMessage(hDlg, IDC_ENDIAN, BM_SETCHECK, BST_CHECKED, 0);
@ -1516,7 +1554,6 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
return true;
} break;
case WM_NOTIFY:
{
LPNMHDR lP = (LPNMHDR) lParam;
@ -1589,6 +1626,12 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
Item->item.pszText = num;
} return true;
case 4:
{
int cheat = CALL_WITH_T_SIZE_TYPES_1(GetCheatStatusFromItemIndex, rs_type_size, rs_t=='s', noMisalign, iNum);
sprintf(num, "%d", cheat);
Item->item.pszText = num;
}
//case 4:
// Item->item.pszText = rsaddrs[rsresults[iNum].Index].comment ? rsaddrs[rsresults[iNum].Index].comment : "";
// return true;
@ -1596,7 +1639,23 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
return false;
}
}
/*
Too much work to do for resorting the values, and finding the biggest number
by sorting in ram list doesn't help too much in usually use, so I gave it up.
case LVN_COLUMNCLICK:
{
NMLISTVIEW* pNMListView = (NMLISTVIEW*)lParam;
if (ramSearchSortCol != pNMListView->iSubItem) {
ramSearchSortCol = pNMListView->iSubItem;
ramSearchSortAsc = true;
}
else
ramSearchSortAsc = !ramSearchSortAsc;
UpdateSortColumnIcon(pNMListView->hdr.hwndFrom, ramSearchSortCol, ramSearchSortAsc);
break;
}
*/
case NM_RCLICK:
{
// go to the address in Hex Editor
@ -1610,6 +1669,7 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
break;
}
//case LVN_ODCACHEHINT: //Copied this bit from the MSDN virtual listbox code sample. Eventually it should probably do something.
//{
// LPNMLVCACHEHINT lpCacheHint = (LPNMLVCACHEHINT)lParam;
@ -2116,7 +2176,7 @@ void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidt
{
LVCOLUMN Col;
Col.mask = LVCF_FMT | LVCF_ORDER | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
Col.fmt = LVCFMT_CENTER;
Col.fmt = LVCFMT_RIGHT;
for (int i = 0; i < numColumns; i++)
{
Col.iOrder = i;

View File

@ -32,4 +32,9 @@ void DoRamSearchOperation(); //Perform a search
extern HWND RamSearchHWnd;
extern LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Too much work to do for resorting the values, and finding the biggest number
// by sorting in ram list doesn't help too much in usually use, so I gave it up.
// static int CALLBACK RamSearchItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort);
// extern void UpdateSortColumnIcon(HWND hwndListView, int sortColumn, bool sortAsc);
#endif

View File

@ -297,7 +297,7 @@ FONT 8, "Tahoma", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "OK",IDOK,261,274,50,14
PUSHBUTTON "Cancel",BTN_CANCEL,205,274,50,14
CONTROL "List2",LV_MAPPING,"SysListView32",LVS_REPORT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,304,243
CONTROL "List2",LV_MAPPING,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,7,7,304,243
PUSHBUTTON "Restore Defaults",BTN_RESTORE_DEFAULTS,7,274,75,14
COMBOBOX COMBO_FILTER,32,255,279,193,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Filter:",65484,6,255,21,12,SS_CENTERIMAGE | NOT WS_GROUP
@ -578,10 +578,10 @@ BEGIN
CONTROL "Set high-priority thread.",CB_SET_HIGH_PRIORITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,24,102,12
CONTROL "Overclocking (old PPU only).",CB_OVERCLOCKING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,41,101,10
EDITTEXT IDC_EXTRA_SCANLINES,104,55,84,14,ES_AUTOHSCROLL | WS_DISABLED
LTEXT "Post-render scanlines:",IDC_EXTRA_SCANLINES_TEXT,21,57,74,8, WS_DISABLED
LTEXT "Post-render scanlines:",IDC_EXTRA_SCANLINES_TEXT,21,57,74,8,WS_DISABLED
CONTROL "Don't overclock 7-bit samples.",CB_SKIP_7BIT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,10,87,111,10
EDITTEXT IDC_VBLANK_SCANLINES,104,68,84,14,ES_AUTOHSCROLL | WS_DISABLED
LTEXT "VBlank scanlines:",IDC_VBLANK_SCANLINES_TEXT,21,71,76,8, WS_DISABLED
LTEXT "VBlank scanlines:",IDC_VBLANK_SCANLINES_TEXT,21,71,76,8,WS_DISABLED
END
MOVIEOPTIONS DIALOGEX 65520, 76, 147, 222
@ -864,15 +864,15 @@ CAPTION "Name Table Viewer"
FONT 8, "Tahoma", 0, 0, 0x0
BEGIN
GROUPBOX "Name Tables",IDC_NTVIEW_TABLE_BOX,2,0,347,251,WS_TABSTOP
LTEXT "Refresh: More",-1,225,254,50,9
LTEXT "Refresh: More",IDC_STATIC,225,254,50,9
CONTROL "",IDC_NTVIEW_REFRESH_TRACKBAR,"msctls_trackbar32",WS_TABSTOP,275,254,50,11
LTEXT "Less",-1,325,254,18,10
LTEXT "Less",IDC_STATIC,325,254,18,10
LTEXT "Display on scanline:",IDC_NTVIEW_SCANLINE_TEXT,253,269,65,9
EDITTEXT IDC_NTVIEW_SCANLINE,315,267,27,12
CONTROL "Show Scroll Lines",IDC_NTVIEW_SHOW_SCROLL_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,254,69,10
CONTROL "Show Attributes",IDC_NTVIEW_SHOW_ATTRIBUTES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,265,69,10
CONTROL "Ignore Palettes",IDC_NTVIEW_HIDE_PALETTES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,276,69,10
GROUPBOX "Current Mirroring",-1,2,289,170,59
GROUPBOX "Current Mirroring",IDC_STATIC,2,289,170,59
CONTROL "Horizontal",IDC_NTVIEW_MIRROR_HORIZONTAL,"Button",BS_AUTORADIOBUTTON,6,300,47,10
CONTROL "Vertical",IDC_NTVIEW_MIRROR_VERTICAL,"Button",BS_AUTORADIOBUTTON,6,311,39,10
CONTROL "Four Screen",IDC_NTVIEW_MIRROR_FOUR_SCREEN,"Button",BS_AUTORADIOBUTTON,6,322,55,10
@ -880,7 +880,7 @@ BEGIN
CONTROL "Single Screen 1",IDC_NTVIEW_MIRROR_SS_TABLE_1,"Button",BS_AUTORADIOBUTTON,85,311,75,10
CONTROL "Single Screen 2",IDC_NTVIEW_MIRROR_SS_TABLE_2,"Button",BS_AUTORADIOBUTTON,85,322,75,10
CONTROL "Single Screen 3",IDC_NTVIEW_MIRROR_SS_TABLE_3,"Button",BS_AUTORADIOBUTTON,85,333,75,10
GROUPBOX "Properties",-1,174,289,175,59
GROUPBOX "Properties",IDC_STATIC,174,289,175,59
LTEXT "Tile ID:",IDC_NTVIEW_PROPERTIES_LINE_1,184,300,150,10
LTEXT "X / Y:",IDC_NTVIEW_PROPERTIES_LINE_2,184,311,150,10
LTEXT "PPU Address:",IDC_NTVIEW_PROPERTIES_LINE_3,184,322,150,10
@ -1449,7 +1449,7 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_
CAPTION " RAM Search"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_RAMLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,9,9,214,151,WS_EX_CLIENTEDGE
CONTROL "",IDC_RAMLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,9,9,214,151,WS_EX_CLIENTEDGE
PUSHBUTTON "&Search",IDC_C_SEARCH,226,9,52,16
PUSHBUTTON "&Add Cheat",IDC_C_ADDCHEAT,226,130,52,14,WS_DISABLED
PUSHBUTTON "&Watch",IDC_C_WATCH,226,114,52,14
@ -1838,12 +1838,12 @@ BEGIN
POPUP "E&mulation Speed"
BEGIN
MENUITEM "&Pause", ID_NES_PAUSE
MENUITEM "&Turbo", ID_NES_TURBO
MENUITEM "&Turbo", ID_NES_TURBO
MENUITEM SEPARATOR
MENUITEM "Speed &Up", ID_NES_SPEEDUP
MENUITEM "Slow &Down", ID_NES_SLOWDOWN
MENUITEM "&Slowest Speed", ID_NES_SLOWESTSPEED
MENUITEM "&Normal Speed", ID_NES_NORMALSPEED
MENUITEM "&Normal Speed", ID_NES_NORMALSPEED
MENUITEM "Set &Custom Speed", ID_EMULATIONSPEED_CUSTOMSPEED
MENUITEM SEPARATOR
MENUITEM "Set FrameAdvance Delay", ID_EMULATIONSPEED_SETFRAMEADVANCEDELAY

View File

@ -366,6 +366,7 @@
#define IDD_TASEDITOR_SAVINGOPTIONS 289
#define IDD_SYMBOLIC_DEBUG_NAMING 290
#define DLG_SNESPAD 291
#define IDB_PNG2 298
#define MENU_HIDE_MENU 300
#define COMBO_FILTER 300
#define IDC_EDIT_AUTHORINFO 300
@ -1273,15 +1274,15 @@
#define MW_ValueLabel2 65423
#define MW_ValueLabel1 65426
#define IDC_STATIC_SLASHTEXT 65442
#define IDC_BOOKMARK_NAME_TEXT 65535
#define ID_CDL 65535
#define IDC_NTVIEW_SCANLINE_TEXT 65535
#define IDC_BOOKMARK_NAME_TEXT 65532
#define ID_CDL 65533
#define IDC_NTVIEW_SCANLINE_TEXT 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 296
#define _APS_NEXT_RESOURCE_VALUE 302
#define _APS_NEXT_COMMAND_VALUE 40600
#define _APS_NEXT_CONTROL_VALUE 1310
#define _APS_NEXT_SYMED_VALUE 101

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,6 @@ void SetMainWindowStuff();
void GetMouseData(uint32 (&md)[3]);
void GetMouseRelative(int32 (&md)[3]);
//void ChangeMenuItemText(int menuitem, string text);
void UpdateMenuHotkeys();
template<int BUFSIZE>
inline std::string GetDlgItemText(HWND hDlg, int nIDDlgItem) {
@ -54,31 +53,77 @@ inline std::wstring GetDlgItemTextW(HWND hDlg, int nIDDlgItem) {
return buf;
}
enum FCEUMENU_HWND {
FCEUMENU_CONTEXT_OFF, // NoGame
FCEUMENU_CONTEXT_GAME, // Game+NoMovie
FCEUMENU_CONTEXT_PLAYING_READONLY, //Game+Movie+Playing+ReadOnly
FCEUMENU_CONTEXT_PLAYING_READWRITE, //Game+Movie+Playing+ReadWrite
FCEUMENU_CONTEXT_RECORDING_READONLY, //Game+Movie+Recording+ReadOnly
FCEUMENU_CONTEXT_RECORDING_READWRITE, //Game+Movie+Recording+Readwrite
FCEUMENU_CONTEXT, // parent menu of all context menus,
// not recommended to use it since there's duplicate ids in context menus,
// unless you're quite sure the id is unique in all submenus.
FCEUMENU_MAIN, // main fceux menu
FCEUMENU_LIMIT
};
#define FCEUMENU_INDEX int
// the index start from 0 should exaclty match the submenu index defined in the resource file until the last one;
#define FCEUMENU_CONTEXT_OFF 0 // NoGame
#define FCEUMENU_CONTEXT_GAME 1 // Game+NoMovie
#define FCEUMENU_CONTEXT_PLAYING_READONLY 2 //Game+Movie+Playing+ReadOnly
#define FCEUMENU_CONTEXT_PLAYING_READWRITE 3 //Game+Movie+Playing+ReadWrite
#define FCEUMENU_CONTEXT_RECORDING_READONLY 4 //Game+Movie+Recording+ReadOnly
#define FCEUMENU_CONTEXT_RECORDING_READWRITE 5 //Game+Movie+Recording+Readwrite
#define FCEUMENU_CONTEXT 6 // parent menu of all context menus,
// not recommended to use it since there's duplicate ids in context menus,
// unless you're quite sure the id is unique in all submenus.
#define FCEUMENU_MAIN 7 // main fceux menu
#define FCEUMENU_MAIN_INPUTDISPLAY 8 // a special one for the input display
// "&Config"->"&Display"-> "&Input Display"
#define FCEUMENU_LIMIT 9
#define GetHMENU(index, hmenu) \
switch (index) \
{ \
case FCEUMENU_MAIN: hmenu = fceumenu; break; \
case FCEUMENU_MAIN_INPUTDISPLAY: hmenu = GetSubMenu(GetSubMenu(GetSubMenu(fceumenu, 2), 2), 0); break; \
case FCEUMENU_CONTEXT: hmenu = hfceuxcontext; break; \
default: hmenu = GetSubMenu(hfceuxcontext, index); \
} \
/* used to indicate which parent menu is the HOTKEYMENUINDEX belongs to.
How to use:
use MENU_BELONG(menu_name) to make it to the correct bit, menu_name must
be the FCEUMENU_XXXX defined above, and FCEUMENU_ should be ignored. For
example, MENU_BELONG(CONTEXT_RECORDING_READONLY) means a menu is belong
to FCEUMENU_CONTEXT_PLAYING_READONLY as Game+Movie+Recording+ReadOnly.
Since the menus with the same id can coexist in different parent menus,
the identifier can be multipled by OR. You can also the predefined
BELONG_XXXX_XXXX.
*/
#define MENU_BELONG_INT int
#define MENU_BELONG(menu_index) (1 << FCEUMENU_##menu_index)
// ReadOnly and ReadWrite in playing status
#define BELONG_CONTEXT_PLAYING (MENU_BELONG(CONTEXT_PLAYING_READONLY) | MENU_BELONG(CONTEXT_PLAYING_READWRITE))
// ReadOnly and ReadWrite in recording status
#define BELONG_CONTEXT_RECORDING (MENU_BELONG(CONTEXT_RECORDING_READONLY) | MENU_BELONG(CONTEXT_RECORDING_READWRITE))
// ReadOnly in playing and recording status
#define BELONG_CONTEXT_READONLY (MENU_BELONG(CONTEXT_PLAYING_READONLY) | MENU_BELONG(CONTEXT_RECORDING_READONLY))
// Readwrite in playing and recording status
#define BELONG_CONTEXT_READWRITE (MENU_BELONG(CONTEXT_PLAYING_READWRITE) | MENU_BELONG(CONTEXT_RECORDING_READWRITE))
// All status with movie
#define BELONG_CONTEXT_MOVIE_ALL (MENU_BELONG(CONTEXT_PLAYING_READONLY) | MENU_BELONG(CONTEXT_PLAYING_READWRITE) | MENU_BELONG(CONTEXT_RECORDING_READONLY) | MENU_BELONG(CONTEXT_RECORDING_READWRITE))
// All status without movie
#define BELONG_CONTEXT_NOMOVIE (MENU_BELONG(CONTEXT_OFF)| MENU_BELONG(CONTEXT_GAME))
// All status when game is loaded
#define BELONG_CONTEXT_RUNNING (BELONG_CONTEXT_MOVIE_ALL | MENU_BELONG(CONTEXT_GAME))
// All context menus
#define BELONG_CONTEXT_ALL (BELONG_CONTEXT_NOMOVIE | BELONG_CONTEXT_MOVIE_ALL)
// ALL menus
#define BELONG_ALL (BELONG_CONTEXT_ALL | MENU_BELONG(MAIN))
#define IsMenuBelongsTo(menu_index, hmenu_ident) (1 << menu_index & hmenu_ident)
struct HOTKEYMENUINDEX {
int menu_id; // menu ID
int cmd_id; // hotkey ID
int hmenu_index = FCEUMENU_MAIN; // whitch menu it belongs to, refers to FCEUMENU_HWND
MENU_BELONG_INT hmenu_ident = MENU_BELONG(MAIN); // whitch menu it belongs to, can be multiple, refers to HOTKEYMENU_PARENTMENU_INDEX
int flags = MF_BYCOMMAND; // flags when searching and modifying menu item, usually MF_BYCOMMAND
// returns an std::string contains original menu text followed with shortcut keys.
std::string getQualifiedMenuText();
std::string getQualifiedMenuText(MENU_BELONG_INT parent_index = MENU_BELONG(MAIN));
// this is used when you only want to create a qualified menu text String
static std::string getQualifiedMenuText(char* text, int cmdid);
int updateMenuText();
HOTKEYMENUINDEX(int id, int cmd, int menu = FCEUMENU_MAIN, int _flags = MF_BYCOMMAND) : menu_id(id), cmd_id(cmd), hmenu_index(menu), flags(_flags) {}
void updateMenuText(FCEUMENU_INDEX index);
HOTKEYMENUINDEX(int _id, int _cmd, MENU_BELONG_INT _menu = MENU_BELONG(MAIN), int _flags = MF_BYCOMMAND) : menu_id(_id), cmd_id(_cmd), hmenu_ident(_menu), flags(_flags) {}
};
void UpdateMenuHotkeys(FCEUMENU_INDEX index);
int GetCurrentContextIndex();
#endif

View File

@ -113,6 +113,11 @@ bool DebuggerWasUpdated = false; //To prevent the debugger from updating things
bool AutoResumePlay = false;
char romNameWhenClosingEmulator[2048] = {0};
// indicator for the open in archive dialog that if the load was canceled by the user.
// TODO: Since I can't think of a better way to indicate it, hope someone could imporve it.
bool archiveManuallyCanceled = false;
FCEUGI::FCEUGI()
: filename(0),
archiveFilename(0) {
@ -418,7 +423,11 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
{
// Although !fp, if the operation was canceled from archive select dialog box, don't show the error message;
if (!silent && !archiveManuallyCanceled)
FCEU_PrintError("打开 \"%s\" 错误!", name);
FCEU_PrintError("Error opening \"%s\"!", name);
// Set it back to false, since user might not load ROM from dialog the next time.
// TODO: find a better way to do this.
archiveManuallyCanceled = false;
return 0;
}
else if (fp->archiveFilename != "")

View File

@ -11,6 +11,11 @@
extern bool bindSavestate;
// indicator for the open in archive dialog that if the load was canceled by the user.
// TODO: Since I can't think of a better way to indicate it, hope someone could imporve it.
extern bool archiveManuallyCanceled;
struct FCEUFILE {
//the stream you can use to access the data
//std::iostream *stream;

View File

@ -3348,6 +3348,30 @@ static void gui_drawline_internal(int x1, int y1, int x2, int y2, bool lastPixel
}
}
// draw a rect on gui_data
static void gui_drawbox_internal(int x1, int y1, int x2, int y2, uint32 colour) {
if (x1 > x2)
swap<int>(x1, x2);
if (y1 > y2)
swap<int>(y1, y2);
if (x1 < 0)
x1 = -1;
if (y1 < 0)
y1 = -1;
if (x2 >= LUA_SCREEN_WIDTH)
x2 = LUA_SCREEN_WIDTH;
if (y2 >= LUA_SCREEN_HEIGHT)
y2 = LUA_SCREEN_HEIGHT;
//gui_prepare();
gui_drawline_internal(x1, y1, x2, y1, true, colour);
gui_drawline_internal(x1, y2, x2, y2, true, colour);
gui_drawline_internal(x1, y1, x1, y2, true, colour);
gui_drawline_internal(x2, y1, x2, y2, true, colour);
}
// draw fill rect on gui_data
static void gui_fillbox_internal(int x1, int y1, int x2, int y2, uint32 colour)
{
@ -3375,38 +3399,6 @@ static void gui_fillbox_internal(int x1, int y1, int x2, int y2, uint32 colour)
}
}
// draw a rect on gui_data
static void gui_drawbox_internal(int x1, int y1, int x2, int y2, uint32 colour) {
if (x1 > x2)
swap<int>(x1, x2);
if (y1 > y2)
swap<int>(y1, y2);
if (x1 < 0)
x1 = -1;
if (y1 < 0)
y1 = -1;
if (x2 >= LUA_SCREEN_WIDTH)
x2 = LUA_SCREEN_WIDTH;
if (y2 >= LUA_SCREEN_HEIGHT)
y2 = LUA_SCREEN_HEIGHT;
//gui_prepare();
int h = y2 - y1 + 1;
int w = x2 - x1 + 1;
if(w < 2 || h < 2)
gui_fillbox_internal(x1,y1,x2,y2,colour);
else
{
gui_drawline_internal(x1, y1, x2, y1, true, colour); //top
gui_drawline_internal(x1, y2, x2, y2, true, colour); //bottom
gui_drawline_internal(x1, y1+1, x1, y2-1, true, colour); //left
gui_drawline_internal(x2, y1+1, x2, y2-1, true, colour); //right
}
}
enum
{
GUI_COLOUR_CLEAR

View File

@ -75,8 +75,8 @@
</PropertyGroup>
<PropertyGroup Label="Globals" Condition="'$(v141_xp_Installed)'=='true'">
<PlatformToolset>v141_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140_xp\Microsoft.Cpp.$(Platform).v140_xp.props" Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140_xp\Microsoft.Cpp.$(Platform).v140_xp.props')"/>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140_xp\Microsoft.Cpp.$(Platform).v140_xp.props" Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140_xp\Microsoft.Cpp.$(Platform).v140_xp.props')" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@ -1439,6 +1439,9 @@
<None Include="..\src\ops.inc" />
<None Include="..\src\pputile.inc" />
</ItemGroup>
<ItemGroup>
<Image Include="..\src\drivers\win\res\bitmap21.bmp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -1939,4 +1939,7 @@
<ItemGroup>
<CustomBuild Include="..\src\auxlib.lua" />
</ItemGroup>
<ItemGroup>
<Image Include="..\src\drivers\win\res\bitmap21.bmp" />
</ItemGroup>
</Project>