Add import/export bookmarks feature to Hex Editor.

This commit is contained in:
owomomo 2020-10-05 10:05:27 +08:00
parent e0aa1e1edc
commit d4a8962695
10 changed files with 3653 additions and 3191 deletions

View File

@ -132,6 +132,7 @@ extern int RomFreezeColorB;
extern int HexBoundColorR;
extern int HexBoundColorG;
extern int HexBoundColorB;
extern int importBookmarkProps;
//adelikat: Hacky fix for Ram Watch recent menu
char* ramWatchRecent[] = {0, 0, 0, 0, 0};
@ -459,6 +460,7 @@ static CFGSTRUCT fceuconfig[] =
AC(HexBoundColorR),
AC(HexBoundColorG),
AC(HexBoundColorB),
AC(importBookmarkProps),
//ACS(memwLastfile[2048]),
AC(AutoRWLoad),

View File

@ -628,7 +628,7 @@ void SetHeaderData(HWND hwnd, iNES_HEADER* header) {
// Mapper#
int mapper = header->ROM_type >> 4 | header->ROM_type2 & 0xF0;
if (ines20)
mapper |= (header->ROM_type3 & 0x0F) << 8;
mapper |= (header->ROM_type3 & 0xF0) << 4;
sprintf(buf, "%d ", mapper);
if (SendDlgItemMessage(hwnd, IDC_MAPPER_COMBO, CB_SELECTSTRING, 0, (LPARAM)buf) == CB_ERR)
SetDlgItemText(hwnd, IDC_MAPPER_COMBO, buf);

View File

@ -171,7 +171,7 @@ unsigned int skippy = 0; //Frame skip
int frameSkipCounter = 0; //Counter for managing frame skip
// Contains the names of the overridden standard directories
// in the order roms, nonvol, states, fdsrom, snaps, cheats, movies, memwatch, basic bot, macro, input presets, lua scripts, avi, base
char *directory_names[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
char *directory_names[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int edit_id[14] = { EDIT_ROM, EDIT_BATTERY, EDIT_STATE, EDIT_FDSBIOS, EDIT_SCREENSHOT, EDIT_CHEAT, EDIT_MOVIE, EDIT_MEMWATCH, EDIT_BOT, EDIT_MACRO, EDIT_PRESET, EDIT_LUA, EDIT_AVI, EDIT_ROOT };
int browse_btn_id[14] = {BUTTON_ROM, BUTTON_BATTERY, BUTTON_STATE, BUTTON_FDSBIOS, BUTTON_SCREENSHOT, BUTTON_CHEAT, BUTTON_MOVIE, BUTTON_MEMWATCH, BUTTON_BOT, BUTTON_MACRO, BUTTON_PRESET, BUTTON_LUA, BUTTON_AVI, BUTTON_ROOT };
std::string cfgFile = "fceux.cfg";
@ -286,7 +286,7 @@ void DefaultDirectoryWalker(void (*callback)(const char*))
sprintf(
TempArray,
"%s\\%s",
directory_names[NUMBER_OF_DEFAULT_DIRECTORIES] ? directory_names[NUMBER_OF_DEFAULT_DIRECTORIES] : BaseDirectory.c_str(),
directory_names[NUMBER_OF_DEFAULT_DIRECTORIES - 1] ? directory_names[NUMBER_OF_DEFAULT_DIRECTORIES - 1] : BaseDirectory.c_str(),
default_directory_names[curr_dir]
);

View File

@ -141,6 +141,7 @@ int GetAddyFromCoord(int x,int y);
void AutoScrollFromCoord(int x,int y);
LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK MemFindCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK importBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void FindNext();
void OpenFindDialog();
static int GetFileData(uint32 offset);
@ -713,7 +714,7 @@ void UpdateColorTable()
TextColorList[i] = RGB(HexForeColorR,HexForeColorG,HexForeColorB); //Regular color text - 2 columns
}
for (j=0;j<nextBookmark;j++)
for (j=0;j<hexBookmarks.bookmarkCount;j++)
{
if(hexBookmarks[j].editmode != EditingMode) continue;
if(((int)hexBookmarks[j].address >= CurOffset) && ((int)hexBookmarks[j].address < CurOffset+DataAmount))
@ -912,73 +913,7 @@ void UnfreezeAllRam() {
return;
}
/*
int saveBookmarks(HWND hwnd)
{
char name[513] = { 0 };
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hInstance = fceu_hInstance;
ofn.lpstrTitle = "Save bookmarks as...";
ofn.lpstrFilter = "Bookmark list (*.bld)\0*.lst\0All Files (*.*)\0*.*\0\0";
strcpy(name, mass_replace(GetRomName(), "|", ".").c_str());
ofn.lpstrFile = name;
ofn.lpstrDefExt = "bld";
ofn.nMaxFile = 256;
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
ofn.hwndOwner = hwnd;
bool success = false;
if (GetSaveFileName(&ofn))
{
FILE* bld = fopen(name, "wb");
if (bld)
{
fwrite("BOOKMARKLIST", strlen("BOOKMARKLIST"), 1, bld);
extern int storeHexPreferences(FILE*);
success = storeHexPreferences(bld);
fclose(bld);
}
}
return success;
}
int loadBookmarks(HWND hwnd)
{
char nameo[2048] = { 0 };
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hInstance = fceu_hInstance;
ofn.lpstrTitle = "Load bookmarks...";
ofn.lpstrFilter = "Bookmark list (*.bld)\0*.lst\0All Files (*.*)\0*.*\0\0";
ofn.lpstrFile = nameo;
ofn.nMaxFile = 256;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.hwndOwner = hwnd;
int success = 0;
if (GetOpenFileName(&ofn))
{
char buffer[13] = { 0 };
FILE* bld = fopen(nameo, "r");
if (bld)
{
fread(bld, strlen("BOOKMARKLIST"), 1, bld);
if (!strcpy(buffer, "BOOKMARKLIST"))
{
extern int loadHexPreferences(FILE*);
success = loadHexPreferences(bld);
}
fclose(bld);
}
}
return success;
}
*/
void FreezeRam(int address, int mode, int final){
// mode: -1 == Unfreeze; 0 == Toggle; 1 == Freeze
if(FrozenAddressCount <= 256 && (address < 0x2000) || ((address >= 0x6000) && (address <= 0x7FFF))){
@ -1427,12 +1362,12 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
int key_num;
sscanf(buf, "%d", &key_num);
key_num = (key_num + 9) % 10;
if (hexBookmarkShortcut[key_num] != -1)
if (hexBookmarks.shortcuts[key_num] != -1)
{
int address = hexBookmarks[hexBookmarkShortcut[key_num]].address;
int address = hexBookmarks[hexBookmarks.shortcuts[key_num]].address;
if (address != -1)
{
ChangeMemViewFocus(hexBookmarks[hexBookmarkShortcut[key_num]].editmode, address, -1);
ChangeMemViewFocus(hexBookmarks[hexBookmarks.shortcuts[key_num]].editmode, address, -1);
UpdateColorTable();
}
}
@ -1857,7 +1792,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
{
if (foundBookmark == -1)
{
if (nextBookmark >= 64)
if (hexBookmarks.bookmarkCount >= 64)
MessageBox(hwnd, "Can't set more than 64 bookmarks.", "Error", MB_OK | MB_ICONERROR);
else
{
@ -2232,7 +2167,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
}
case MENU_MV_BOOKMARKS_RM_ALL:
if (nextBookmark)
if (hexBookmarks.bookmarkCount)
{
if (MessageBox(hwnd, "Remove All Bookmarks?", "Bookmarks", MB_YESNO | MB_ICONINFORMATION) == IDYES)
{
@ -2241,15 +2176,280 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
}
}
return 0;
/*
case MENU_MV_BOOKMARKS_EXPORT:
if (!saveBookmarks(hwnd))
MessageBox(hwnd, "Error saving bookmarks.", "Error", MB_OK | MB_ICONERROR);
case ID_BOOKMARKS_EXPORT:
{
char name[2048] = { 0 };
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hInstance = fceu_hInstance;
ofn.lpstrTitle = "Save bookmarks as...";
ofn.lpstrFilter = "Hex Editor Bookmark list (*.hbm)\0*.hbm\0All Files (*.*)\0*.*\0\0";
strcpy(name, mass_replace(GetRomName(), "|", ".").c_str());
ofn.lpstrFile = name;
ofn.lpstrDefExt = "hbm";
ofn.nMaxFile = 2048;
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
ofn.hwndOwner = hwnd;
int success = false;
if (GetSaveFileName(&ofn))
{
FILE* bld = fopen(name, "wb");
if (bld)
{
// write the header
fwrite("HexBookmarkList", strlen("HexBookmarkList"), 1, bld);
// it shares the same logic of creating the hexpreference part of .deb file
extern int storeHexPreferences(FILE*, HexBookmarkList& = hexBookmarks);
if (!storeHexPreferences(bld))
success = true;
fclose(bld);
}
if (!success)
MessageBox(hwnd, "Error saving bookmarks.", "Error saving bookmarks", MB_OK | MB_ICONERROR);
}
return 0;
case MENU_MV_BOOKMARKS_IMPORT:
loadBookmarks(hwnd);
return 0;
*/
}
case ID_BOOKMARKS_IMPORT:
{
char nameo[2048] = { 0 };
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hInstance = fceu_hInstance;
ofn.lpstrTitle = "Load bookmarks...";
ofn.lpstrFilter = "Hex Editor Bookmarks (*.hbm)\0*.hbm\0All Files (*.*)\0*.*\0\0";
ofn.lpstrFile = nameo;
ofn.lpstrDefExt = "hbm";
ofn.nMaxFile = 2048;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.hwndOwner = hwnd;
bool success = false;
if (GetOpenFileName(&ofn))
{
char buffer[128] = { 0 };
FILE* bld = fopen(nameo, "r");
if (bld)
{
// Read the header to know it's hex bookmark list
fread(buffer, strlen("HexBookmarkList"), 1, bld);
if (!strcmp(buffer, "HexBookmarkList"))
{
HexBookmarkList import;
// it shares the same logic of creating the hexpreference part of .deb file
extern int loadHexPreferences(FILE*, HexBookmarkList& = hexBookmarks);
if (!loadHexPreferences(bld, import) && import.bookmarkCount > 0)
{
if (importBookmarkProps & IMPORT_DISCARD_ORIGINAL)
{
if (importBookmarkProps & IMPORT_OVERWRITE_NO_PROMPT || hexBookmarks.bookmarkCount == 0 || MessageBox(hwnd, "All your existing bookmarks will be discarded after importing the new bookmarks! Do you want to continue?", "Bookmark Import", MB_YESNO | MB_ICONWARNING) == IDYES)
for (i = 0; i < import.bookmarkCount; ++i)
{
hexBookmarks[i].address = import[i].address;
hexBookmarks[i].editmode = import[i].editmode;
strcpy(hexBookmarks[i].description, import[i].description);
memcpy(hexBookmarks.shortcuts, import.shortcuts, sizeof(hexBookmarks.shortcuts));
hexBookmarks.bookmarkCount = import.bookmarkCount;
hexBookmarks.shortcutCount = import.shortcutCount;
}
}
else
{
// conflict bookmark count
int conflictBookmarkCount = 0;
// the conflict bookmark indexes of the main list
int conflictBookmarkIndex[64];
// conflict shortcut count
int conflictShortcutCount = 0;
// discarded bookmark count
int discardBookmarkCount = 0;
// bookmark that is out of scope
int outOfRangeBookmarkCount = 0;
// store the count of bookmarks after importing finished
int finalBookmarkCount = hexBookmarks.bookmarkCount;
// the reference index number in main bookmark list
// -1 means this bookmark is not be indexed
int indexRef[64];
memset(indexRef, -1, sizeof(indexRef));
for (i = 0; i < import.bookmarkCount; ++i)
{
bool conflict = false;
for (j = 0; j < hexBookmarks.bookmarkCount; ++j)
{
// to find if there are any conflict bookmarks
// currently, one address can have only one bookmark
// if the address and editmode are the same, then they are considered conflict
if (import[i].address == hexBookmarks[j].address && import[j].editmode == hexBookmarks[j].editmode)
{
conflictBookmarkIndex[conflictBookmarkCount] = i;
indexRef[i] = j;
++conflictBookmarkCount;
conflict = true;
break;
}
}
// after a loop, this bookmark doesn't have conflict with the original one
if (!conflict)
if (finalBookmarkCount >= 64)
// the total bookmark count has reached the limit of bookmarks (64),
// discard it
++discardBookmarkCount;
else if (import[j].address > GetMaxSize(import[j].editmode))
// the bookmark is out of valid range for current game,
// discard it.
++outOfRangeBookmarkCount;
else
{
// if the bookmark is still not discarded,
// then it's not a conflict one, append it to the last of the main list
indexRef[i] = finalBookmarkCount;
hexBookmarks[finalBookmarkCount].address = import[i].address;
hexBookmarks[finalBookmarkCount].editmode = import[i].editmode;
strcpy(hexBookmarks[finalBookmarkCount].description, import[i].description);
++finalBookmarkCount;
}
}
// the result of overwriting the shortcuts
int shortcutListOverwrite[10];
memcpy(shortcutListOverwrite, hexBookmarks.shortcuts, sizeof(hexBookmarks.shortcuts));
int shortcutListOverwriteCount = hexBookmarks.shortcutCount;
// the result of keep the shortcut as original
int shortcutListKeep[10];
memcpy(shortcutListKeep, hexBookmarks.shortcuts, sizeof(hexBookmarks.shortcuts));
int shortcutListKeepCount = hexBookmarks.shortcutCount;
for (i = 0; i < 10; ++i)
if (import.shortcuts[i] != -1)
{
bool repeat = false;
for (j = 0; j < 10; ++j)
if (indexRef[import.shortcuts[i]] == hexBookmarks.shortcuts[j] && i != j)
{
// the slot in the original list had this bookmark but different
// slot, remove the bookmark in the original slot
shortcutListOverwrite[j] = -1;
--shortcutListOverwriteCount;
++conflictShortcutCount;
repeat = true;
break;
}
if (shortcutListOverwrite[i] == -1)
++shortcutListOverwriteCount;
shortcutListOverwrite[i] = indexRef[import.shortcuts[i]];
// after a loop, the original list doesn't have a slot with same
// bookmark but different slot, and the slot in original list
// is empty, then the bookmark can occupy it.
if (!repeat && hexBookmarks.shortcuts[i] == -1)
{
shortcutListKeep[i] = indexRef[import.shortcuts[i]];
++shortcutListKeepCount;
}
}
int tmpImportBookmarkProps = importBookmarkProps;
bool continue_ = true;
// show the prompt message if there are conflicts
if (!(tmpImportBookmarkProps & IMPORT_OVERWRITE_NO_PROMPT) && (conflictBookmarkCount || conflictShortcutCount))
{
char units[32];
strcpy(buffer, "The importing bookmark list has ");
sprintf(units, "%d duplicate bookmark", conflictBookmarkCount);
if (conflictBookmarkCount != 1)
strcat(units, "s");
strcat(buffer, units);
if (conflictShortcutCount)
{
if (conflictBookmarkCount) strcat(buffer, " and ");
sprintf(units, "%d conflict shortcut", conflictShortcutCount);
if (conflictShortcutCount != 1)
strcat(units, "s");
strcat(buffer, units);
}
strcat(buffer, " with yours.\r\nYou must choose which side would be reserved. Do you want to continue?");
continue_ = MessageBox(hwnd, buffer, "Bookmark conflict", MB_YESNO | MB_ICONEXCLAMATION) == IDYES && DialogBoxParam(fceu_hInstance, "IMPORTBOOKMARKOPTIONDIALOG", hwnd, importBookmarkCallB, (LPARAM)&tmpImportBookmarkProps);
}
if (continue_)
{
if (tmpImportBookmarkProps & IMPORT_OVERWRITE_BOOKMARK)
// when it is set to overwrite conflicted bookmark, otherwise do nothing
for (i = 0; i < conflictBookmarkCount; ++i)
// the conflict bookmarks are all before the bookmark count in main list
strcpy(hexBookmarks[indexRef[conflictBookmarkIndex[i]]].description, import[conflictBookmarkIndex[i]].description);
// update the bookmark shortcut mapping
if (tmpImportBookmarkProps & IMPORT_OVERWRITE_SHORTCUT)
{
memcpy(hexBookmarks.shortcuts, shortcutListOverwrite, sizeof(hexBookmarks.shortcuts));
hexBookmarks.shortcutCount = shortcutListOverwriteCount;
}
else
{
memcpy(hexBookmarks.shortcuts, shortcutListKeep, sizeof(hexBookmarks.shortcuts));
hexBookmarks.shortcutCount = shortcutListKeepCount;
}
// set the count of the main list to the imported count
hexBookmarks.bookmarkCount = finalBookmarkCount;
updateBookmarkMenus(GetSubMenu(GetMenu(hwnd), BOOKMARKS_SUBMENU_POS));
UpdateColorTable();
}
// tell user there are bookmarks that imported failed.
if (discardBookmarkCount || outOfRangeBookmarkCount)
{
char reason[64];
sprintf(buffer, "Import complete, but %d bookmark%s %s are not imported:\n", discardBookmarkCount + outOfRangeBookmarkCount, discardBookmarkCount + outOfRangeBookmarkCount == 1 ? "" : "s", discardBookmarkCount + outOfRangeBookmarkCount == 1 ? "is" : "are");
if (outOfRangeBookmarkCount)
{
sprintf(reason, "%d %s outside the valid address range of the game.", outOfRangeBookmarkCount, outOfRangeBookmarkCount == 1 ? "is" : "are");
strcat(buffer, reason);
}
if (discardBookmarkCount)
{
if (outOfRangeBookmarkCount)
strcat(buffer, "\n");
sprintf(reason, "%d %s discaded due to the list has reached its max limit (64).", discardBookmarkCount, discardBookmarkCount == 1 ? "is" : "are");
strcat(buffer, reason);
}
MessageBox(hwnd, buffer, "Loading Hex Editor bookmarks", MB_OK | MB_ICONEXCLAMATION);
}
}
}
else
MessageBox(hwnd, "An error occurred while loading bookmarks.", "Error loading bookmarks", MB_OK | MB_ICONERROR);
}
else
MessageBox(hwnd, "This file is not a Hex Editor bookmark list.", "Error loading bookmarks", MB_OK | MB_ICONERROR);
fclose(bld);
}
else
MessageBox(hwnd, "Error opening bookmark file", "Error loading bookmarks", MB_OK | MB_ICONERROR);
}
}
return 0;
case ID_BOOKMARKS_OPTION:
{
int tmpImportBookmarkProps = importBookmarkProps;
if (DialogBoxParam(fceu_hInstance, "IMPORTBOOKMARKOPTIONDIALOG", hwnd, importBookmarkCallB, (LPARAM)&tmpImportBookmarkProps))
importBookmarkProps = tmpImportBookmarkProps;
}
return 0;
case MENU_MV_HELP:
OpenHelpWindow(memviewhelp);
return 0;
@ -2554,3 +2754,182 @@ void PalettePoke(uint32 addr, uint8 data)
PALRAM[addr] = data;
}
}
INT_PTR CALLBACK importBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static int* tmpImportBookmarkProps;
static HWND hTipMerge;
static HWND hTipIgnore;
static HWND hTipOverwrite;
static HWND hTipKeep;
static HWND hTipReassign;
static HWND hTipDiscard;
static HWND hTipConfirm;
switch (uMsg)
{
case WM_INITDIALOG:
CenterWindow(hwndDlg);
tmpImportBookmarkProps = (int*)lParam;
if (!(*tmpImportBookmarkProps & IMPORT_OVERWRITE_NO_PROMPT))
CheckDlgButton(hwndDlg, IDC_CHECK_BOOKMARKIMPORTOPTION_CONFIRMEVERYTIMEONCONFLICT, BST_CHECKED);
if (*tmpImportBookmarkProps & IMPORT_DISCARD_ORIGINAL)
{
CheckDlgButton(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_DISCARD, BST_CHECKED);
EnableWindow(GetDlgItem(hwndDlg, IDC_GROUP_BOOKMARKIMPORTOPTION_SOLVECONFLICT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_BOOKMARK), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_SHORTCUT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN), FALSE);
}
else
{
CheckDlgButton(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_MERGE, BST_CHECKED);
EnableWindow(GetDlgItem(hwndDlg, IDC_GROUP_BOOKMARKIMPORTOPTION_SOLVECONFLICT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_BOOKMARK), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_SHORTCUT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN), TRUE);
}
if (*tmpImportBookmarkProps & IMPORT_OVERWRITE_BOOKMARK)
CheckDlgButton(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE, BST_CHECKED);
else
CheckDlgButton(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE, BST_CHECKED);
if (*tmpImportBookmarkProps & IMPORT_OVERWRITE_SHORTCUT)
CheckDlgButton(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN, BST_CHECKED);
else
CheckDlgButton(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP, BST_CHECKED);
TOOLINFO info;
memset(&info, 0, sizeof(TOOLINFO));
info.cbSize = sizeof(TOOLINFO);
info.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
info.hwnd = hwndDlg;
hTipMerge = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, fceu_hInstance, NULL);
info.lpszText = "Merge the importing bookmarks into my list. \nThe non-conflict bookmarks will be append to the last. \nIf bookmarks or shortcuts have conflicts, \nsolve them according to the import settings.";
info.uId = (UINT_PTR)GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_MERGE);
SendMessage(hTipMerge, TTM_ADDTOOL, 0, (LPARAM)&info);
SendMessage(hTipMerge, TTM_SETMAXTIPWIDTH, 0, 8000);
SendMessage(hTipMerge, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
hTipIgnore = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, fceu_hInstance, NULL);
info.lpszText = "If the importing bookmark has the same address \nand edit mode with one of the original bookmarks,\nkeep the exsiting one unchanged.";
info.uId = (UINT_PTR)GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE);
SendMessage(hTipIgnore, TTM_ADDTOOL, 0, (LPARAM)&info);
SendMessage(hTipIgnore, TTM_SETMAXTIPWIDTH, 0, 8000);
SendMessage(hTipIgnore, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
hTipOverwrite = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, fceu_hInstance, NULL);
info.lpszText = "If the importing bookmark has the same address \nand edit mode with one of the existing bookmarks,\noverwrite the information of the existing one with the importing one.";
info.uId = (UINT_PTR)GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE);
SendMessage(hTipOverwrite, TTM_ADDTOOL, 0, (LPARAM)&info);
SendMessage(hTipOverwrite, TTM_SETMAXTIPWIDTH, 0, 8000);
SendMessage(hTipOverwrite, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
hTipKeep = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, fceu_hInstance, NULL);
info.lpszText = "If two different bookmarks from importing and existing \nuse the same shortcut,\nthe shortcut is remained using by the existing one.\nthe importing one will not use the shortcut.";
info.uId = (UINT_PTR)GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP);
SendMessage(hTipKeep, TTM_ADDTOOL, 0, (LPARAM)&info);
SendMessage(hTipKeep, TTM_SETMAXTIPWIDTH, 0, 8000);
SendMessage(hTipKeep, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
hTipReassign = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, fceu_hInstance, NULL);
info.lpszText = "If two different bookmarks from importing and existing \nuse the same shortcut,\nthe shortcut is assigned to the importing one.\nthe existing one will not use the shortcut.";
info.uId = (UINT_PTR)GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN);
SendMessage(hTipReassign, TTM_ADDTOOL, 0, (LPARAM)&info);
SendMessage(hTipReassign, TTM_SETMAXTIPWIDTH, 0, 8000);
SendMessage(hTipReassign, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
hTipDiscard = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, fceu_hInstance, NULL);
info.lpszText = "Discard all existing bookmarks and then import.\nThis is not recommended.";
info.uId = (UINT_PTR)GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_DISCARD);
SendMessage(hTipDiscard, TTM_ADDTOOL, 0, (LPARAM)&info);
SendMessage(hTipDiscard, TTM_SETMAXTIPWIDTH, 0, 8000);
SendMessage(hTipDiscard, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
hTipConfirm = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, fceu_hInstance, NULL);
info.lpszText = "Ask what to do every time when conflict occurs between existing and importing bookmarks.";
info.uId = (UINT_PTR)GetDlgItem(hwndDlg, IDC_CHECK_BOOKMARKIMPORTOPTION_CONFIRMEVERYTIMEONCONFLICT);
SendMessage(hTipConfirm, TTM_ADDTOOL, 0, (LPARAM)&info);
SendMessage(hTipConfirm, TTM_SETMAXTIPWIDTH, 0, 8000);
SendMessage(hTipConfirm, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
break;
case WM_CLOSE:
case WM_QUIT:
DestroyWindow(hTipMerge);
DestroyWindow(hTipIgnore);
DestroyWindow(hTipOverwrite);
DestroyWindow(hTipKeep);
DestroyWindow(hTipReassign);
DestroyWindow(hTipDiscard);
DestroyWindow(hTipConfirm);
EndDialog(hwndDlg, 0);
break;
case WM_COMMAND:
switch (HIWORD(wParam))
{
case BN_CLICKED:
switch (LOWORD(wParam))
{
case IDC_RADIO_BOOKMARKIMPORTOPTION_DISCARD:
EnableWindow(GetDlgItem(hwndDlg, IDC_GROUP_BOOKMARKIMPORTOPTION_SOLVECONFLICT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_BOOKMARK), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_SHORTCUT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN), FALSE);
break;
case IDC_RADIO_BOOKMARKIMPORTOPTION_MERGE:
EnableWindow(GetDlgItem(hwndDlg, IDC_GROUP_BOOKMARKIMPORTOPTION_SOLVECONFLICT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_BOOKMARK), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_BOOKMARKIMPORTOPTION_SHORTCUT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN), TRUE);
break;
case IDOK:
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_BOOKMARKIMPORTOPTION_CONFIRMEVERYTIMEONCONFLICT) == BST_UNCHECKED)
*tmpImportBookmarkProps |= IMPORT_OVERWRITE_NO_PROMPT;
else
*tmpImportBookmarkProps &= ~IMPORT_OVERWRITE_NO_PROMPT;
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_DISCARD))
*tmpImportBookmarkProps |= IMPORT_DISCARD_ORIGINAL;
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_MERGE))
*tmpImportBookmarkProps &= ~IMPORT_DISCARD_ORIGINAL;
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE))
*tmpImportBookmarkProps |= IMPORT_OVERWRITE_BOOKMARK;
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE))
*tmpImportBookmarkProps &= ~IMPORT_OVERWRITE_BOOKMARK;
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN))
*tmpImportBookmarkProps |= IMPORT_OVERWRITE_SHORTCUT;
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP))
*tmpImportBookmarkProps &= ~IMPORT_OVERWRITE_SHORTCUT;
EndDialog(hwndDlg, 1);
break;
case IDCANCEL:
case IDCLOSE:
EndDialog(hwndDlg, 0);
break;
}
}
}
return FALSE;
}

View File

@ -4,15 +4,14 @@ void UpdateMemoryView(int draw_all);
void UpdateColorTable();
void ChangeMemViewFocus(int newEditingMode, int StartOffset,int EndOffset);
void UpdateCaption();
/*
int saveBookmarks(HWND hwnd);
int loadBookmarks(HWND hwnd);
*/
void ApplyPatch(int addr,int size, uint8* data);
void UndoLastPatch();
void SetHexEditorAddress(int gotoaddress);
int GetMaxSize(int editingMode);
extern HWND hMemView, hMemFind;
extern int EditingMode;

View File

@ -26,10 +26,9 @@
#include "memview.h"
#include "common.h"
HexBookmark hexBookmarks[64];
int hexBookmarkShortcut[10] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
int numHexBookmarkShortcut = 0;
int nextBookmark = 0;
int importBookmarkProps = IMPORT_OVERWRITE_NONE;
HexBookmarkList hexBookmarks;
/// Finds the bookmark for a given address
/// @param address The address to find.
@ -45,7 +44,7 @@ int findBookmark(unsigned int address, int editmode)
return -1;
}
for (i=0;i<nextBookmark;i++)
for (i=0;i<hexBookmarks.bookmarkCount;i++)
{
if (hexBookmarks[i].address == address && hexBookmarks[i].editmode == editmode)
return i;
@ -57,11 +56,6 @@ int findBookmark(unsigned int address, int editmode)
BOOL CenterWindow(HWND hwndDlg);
/// Callback function for the name bookmark dialog
/*
TODO: The bookmarks of Debugger and Hex Editor uses the same dialog box,
but different bookmark systems, either decouple their callback into separate
functions or unify them to use the same bookmark system.
*/
INT_PTR CALLBACK nameHexBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// For Hex Editor
@ -96,11 +90,11 @@ INT_PTR CALLBACK nameHexBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
EnableWindow(GetDlgItem(hwndDlg, IDC_BOOKMARK_SHORTCUT_PREFIX_TEXT), FALSE);
for (int i = 0; i < 10; ++i)
if (!shortcut_assigned || hexBookmarkShortcut[i] != -1 && hexBookmarkShortcut[i] != hexBookmarkMsg->bookmark_index)
if (!shortcut_assigned || hexBookmarks.shortcuts[i] != -1 && hexBookmarks.shortcuts[i] != hexBookmarkMsg->bookmark_index)
// this bookmark doesn't have a shortcut, or the shortcut number is occupied but it doesn't belongs to this bookmark
EnableWindow(GetDlgItem(hwndDlg, dlgShortcutRadioCheck[i]), FALSE);
if (!shortcut_assigned && numHexBookmarkShortcut >= 10)
if (!shortcut_assigned && hexBookmarks.shortcutCount >= 10)
{
// all the shortcuts are occupied and this one doesn't have a shortcut, it's impossible to assign a new shortcut
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_SHORTCUT), FALSE);
@ -138,7 +132,7 @@ INT_PTR CALLBACK nameHexBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
EnableWindow(GetDlgItem(hwndDlg, IDC_BOOKMARK_SHORTCUT_PREFIX_TEXT), shortcut_assigned);
for (int i = 0; i < 10; ++i)
EnableWindow(GetDlgItem(hwndDlg, dlgShortcutRadioCheck[i]), shortcut_assigned && (hexBookmarkShortcut[i] == -1 || hexBookmarkShortcut[i] == hexBookmarkMsg->bookmark_index));
EnableWindow(GetDlgItem(hwndDlg, dlgShortcutRadioCheck[i]), shortcut_assigned && (hexBookmarks.shortcuts[i] == -1 || hexBookmarks.shortcuts[i] == hexBookmarkMsg->bookmark_index));
}
break;
case IDOK:
@ -152,7 +146,6 @@ INT_PTR CALLBACK nameHexBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
// Get the view which the address in
editmode = SendDlgItemMessage(hwndDlg, IDC_BOOKMARK_COMBO_VIEW, CB_GETCURSEL, 0, 0);
extern int GetMaxSize(int editingMode);
int MaxSize = GetMaxSize(editmode);
// Update the address
@ -182,11 +175,11 @@ INT_PTR CALLBACK nameHexBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
GetDlgItemText(hwndDlg, IDC_BOOKMARK_DESCRIPTION, hexBookmarkMsg->bookmark->description, 50);
// Update the shortcut key
if (hexBookmarkMsg->shortcut_index != -1 && hexBookmarkShortcut[hexBookmarkMsg->shortcut_index] == hexBookmarkMsg->bookmark_index)
if (hexBookmarkMsg->shortcut_index != -1 && hexBookmarks.shortcuts[hexBookmarkMsg->shortcut_index] == hexBookmarkMsg->bookmark_index)
{
hexBookmarkShortcut[hexBookmarkMsg->shortcut_index] = -1;
--numHexBookmarkShortcut;
hexBookmarks.shortcuts[hexBookmarkMsg->shortcut_index] = -1;
--hexBookmarks.shortcutCount;
}
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_SHORTCUT))
@ -194,8 +187,8 @@ INT_PTR CALLBACK nameHexBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
if (IsDlgButtonChecked(hwndDlg, dlgShortcutRadioCheck[i]))
{
// Update the shortcut index
hexBookmarkShortcut[i] = hexBookmarkMsg->bookmark_index;
++numHexBookmarkShortcut;
hexBookmarks.shortcuts[i] = hexBookmarkMsg->bookmark_index;
++hexBookmarks.shortcutCount;
break;
}
@ -219,38 +212,38 @@ INT_PTR CALLBACK nameHexBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
int addBookmark(HWND hwnd, unsigned int address, int editmode)
{
// Enforce a maximum of 64 bookmarks
if (nextBookmark < 64)
if (hexBookmarks.bookmarkCount < 64)
{
hexBookmarks[nextBookmark].address = address;
hexBookmarks[nextBookmark].editmode = editmode;
sprintf(hexBookmarks[nextBookmark].description, "%s %04X", EditString[editmode], address);
hexBookmarks[hexBookmarks.bookmarkCount].address = address;
hexBookmarks[hexBookmarks.bookmarkCount].editmode = editmode;
sprintf(hexBookmarks[hexBookmarks.bookmarkCount].description, "%s %04X", EditString[editmode], address);
HexBookmarkMsg msg;
// Pre-define a shortcut if possible
for (int i = 0; i < 10; ++i)
if (hexBookmarkShortcut[i] == -1)
if (hexBookmarks.shortcuts[i] == -1)
{
msg.shortcut_index = i;
break;
}
msg.bookmark = &hexBookmarks[nextBookmark];
msg.bookmark_index = nextBookmark;
msg.bookmark = &hexBookmarks[hexBookmarks.bookmarkCount];
msg.bookmark_index = hexBookmarks.bookmarkCount;
// Show the bookmark name dialog
if (DialogBoxParam(fceu_hInstance, "NAMEBOOKMARKDLGMEMVIEW", hwnd, nameHexBookmarkCallB, (LPARAM)&msg))
{
nextBookmark++;
hexBookmarks.bookmarkCount++;
return 0;
}
else
{
if (msg.shortcut_index != -1)
{
if (hexBookmarkShortcut[msg.shortcut_index] != -1)
--numHexBookmarkShortcut;
hexBookmarkShortcut[msg.shortcut_index] = -1;
if (hexBookmarks.shortcuts[msg.shortcut_index] != -1)
--hexBookmarks.shortcutCount;
hexBookmarks.shortcuts[msg.shortcut_index] = -1;
}
return 1;
}
@ -273,7 +266,7 @@ int editBookmark(HWND hwnd, unsigned int index)
// find its shortcut index
for (int i = 0; i < 10; ++i)
if (index == hexBookmarkShortcut[i])
if (index == hexBookmarks.shortcuts[i])
{
msg.shortcut_index = i;
break;
@ -299,23 +292,23 @@ int removeBookmark(unsigned int index)
for (int i = 0; i < 10; ++i)
{
// all the indexes after the deleted one sould decrease by 1
if (hexBookmarkShortcut[i] != -1 && hexBookmarkShortcut[i] > index)
--hexBookmarkShortcut[i];
else if (hexBookmarkShortcut[i] == index)
if (hexBookmarks.shortcuts[i] != -1 && hexBookmarks.shortcuts[i] > index)
--hexBookmarks.shortcuts[i];
else if (hexBookmarks.shortcuts[i] == index)
{
// delete the shortcut index itself
hexBookmarkShortcut[i] = -1;
--numHexBookmarkShortcut;
hexBookmarks.shortcuts[i] = -1;
--hexBookmarks.shortcutCount;
}
}
// At this point it's necessary to move the content of the bookmark list
for (int i=index;i<nextBookmark - 1;i++)
for (int i=index;i<hexBookmarks.bookmarkCount - 1;i++)
{
hexBookmarks[i] = hexBookmarks[i+1];
}
--nextBookmark;
--hexBookmarks.bookmarkCount;
return 0;
}
@ -345,31 +338,38 @@ int toggleBookmark(HWND hwnd, uint32 address, int editmode)
void updateBookmarkMenus(HMENU menu)
{
// Remove all bookmark menus
for (int i = 0; i<nextBookmark + 1; i++)
for (int i = 0; i<hexBookmarks.bookmarkCount + 1; i++)
RemoveMenu(menu, ID_FIRST_BOOKMARK + i, MF_BYCOMMAND);
RemoveMenu(menu, ID_BOOKMARKLIST_SEP, MF_BYCOMMAND);
if (nextBookmark != 0)
if (hexBookmarks.bookmarkCount != 0)
{
// Add the menus again
AppendMenu(menu, MF_SEPARATOR, ID_BOOKMARKLIST_SEP, NULL);
for (int i = 0;i<nextBookmark;i++)
InsertMenu(menu, ID_BOOKMARKS_IMPORT, MF_SEPARATOR | MF_BYCOMMAND, ID_BOOKMARKLIST_SEP, NULL);
for (int i = 0;i<hexBookmarks.bookmarkCount;i++)
{
// Get the text of the menu
char buffer[0x100];
sprintf(buffer, i < 10 ? "&%d. %s:$%04X - %s" : "%d. $%04X - %s", i, EditString[hexBookmarks[i].editmode], hexBookmarks[i].address, hexBookmarks[i].description);
if (i < 9)
sprintf(buffer, "&%d. %s:$%04X - %s", i + 1, EditString[hexBookmarks[i].editmode], hexBookmarks[i].address, hexBookmarks[i].description);
else if (i == 9)
sprintf(buffer, "1&0. %s:$%04X - %s", EditString[hexBookmarks[i].editmode], hexBookmarks[i].address, hexBookmarks[i].description);
else
sprintf(buffer, "%d. %s:$%04X - %s", i + 1, EditString[hexBookmarks[i].editmode], hexBookmarks[i].address, hexBookmarks[i].description);
AppendMenu(menu, MF_STRING, ID_FIRST_BOOKMARK + i, buffer);
InsertMenu(menu, ID_BOOKMARKLIST_SEP, MF_STRING | MF_BYCOMMAND, ID_FIRST_BOOKMARK + i, buffer);
}
for (int i = 0; i < 10; ++i)
{
if (hexBookmarkShortcut[i] != -1)
if (hexBookmarks.shortcuts[i] != -1)
{
char buffer[0x100];
GetMenuString(menu, ID_FIRST_BOOKMARK + hexBookmarkShortcut[i], buffer, 50, MF_BYCOMMAND);
sprintf(&buffer[strlen(buffer)], "\tCtrl+%d\0", (i + 1) % 10);
ModifyMenu(menu, ID_FIRST_BOOKMARK + hexBookmarkShortcut[i], MF_BYCOMMAND, ID_FIRST_BOOKMARK + hexBookmarkShortcut[i], buffer);
char shortcut[16];
GetMenuString(menu, ID_FIRST_BOOKMARK + hexBookmarks.shortcuts[i], buffer, 50, MF_BYCOMMAND);
sprintf(shortcut, "\tCtrl+%d\0", (i + 1) % 10);
strcat(buffer, shortcut);
ModifyMenu(menu, ID_FIRST_BOOKMARK + hexBookmarks.shortcuts[i], MF_BYCOMMAND, ID_FIRST_BOOKMARK + hexBookmarks.shortcuts[i], buffer);
}
}
@ -381,7 +381,7 @@ void updateBookmarkMenus(HMENU menu)
/// @return The address to scroll to or -1 if the bookmark index is invalid.
int handleBookmarkMenu(int bookmark)
{
if (bookmark < nextBookmark)
if (bookmark < hexBookmarks.bookmarkCount)
{
return hexBookmarks[bookmark].address;
}
@ -393,14 +393,19 @@ int handleBookmarkMenu(int bookmark)
/// @param menu Handle of the bookmark menu
void removeAllBookmarks(HMENU menu)
{
for (int i = 0;i<nextBookmark;i++)
for (int i = 0;i<hexBookmarks.bookmarkCount;i++)
{
RemoveMenu(menu, ID_FIRST_BOOKMARK + i, MF_BYCOMMAND);
}
RemoveMenu(menu, ID_BOOKMARKLIST_SEP, MF_BYCOMMAND);
nextBookmark = 0;
numHexBookmarkShortcut = 0;
hexBookmarks.bookmarkCount = 0;
hexBookmarks.shortcutCount = 0;
for (int i = 0; i < 10; ++i)
hexBookmarkShortcut[i] = -1;
}
hexBookmarks.shortcuts[i] = -1;
}
HexBookmark& HexBookmarkList::operator[](int index)
{
return bookmarks[index];
}

View File

@ -23,7 +23,7 @@
#define ID_FIRST_BOOKMARK 30
#define ID_BOOKMARKLIST_SEP (ID_FIRST_BOOKMARK - 1)
typedef struct
typedef struct HEXBOOKMARK
{
char description[51];
unsigned int address;
@ -37,10 +37,25 @@ typedef struct
int shortcut_index = -1;
} HexBookmarkMsg;
extern HexBookmark hexBookmarks[64];
extern int hexBookmarkShortcut[10];
extern int numHexBookmarkShortcut;
extern int nextBookmark;
typedef struct {
HexBookmark bookmarks[64];
int shortcuts[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
int bookmarkCount = 0;
int shortcutCount = 0;
HexBookmark& operator[](int index);
} HexBookmarkList;
#define IMPORT_OVERWRITE_NONE 0 // Overwrite nothing
#define IMPORT_OVERWRITE_BOOKMARK 1 // Overwrite duplicated bookmarks but don't overwrite duplicated shortcuts
#define IMPORT_OVERWRITE_SHORTCUT 2 // Overwrite duplicated shortcuts but don't overwrite duplicated bookmarks
#define IMPORT_OVERWRITE_ALL (IMPORT_OVERWRITE_BOOKMARK | IMPORT_OVERWRITE_SHORTCUT), // (3) Overwrite duplicated bookmarks and shortcuts
#define IMPORT_OVERWRITE_NO_PROMPT 4 // Not confirm for what to do when conflicts
#define IMPORT_DISCARD_ORIGINAL 8 // Discard all the original bookmarks
extern int importBookmarkProps;
extern HexBookmarkList hexBookmarks;
int findBookmark(unsigned int address, int editmode);
int addBookmark(HWND hwnd, unsigned int address, int editmode);

View File

@ -120,37 +120,38 @@ int storeDebuggerPreferences(FILE* f)
* Stores the preferences from the Hex window
*
* @param f File to write the preferences to
* @param source The source the preferences are read from
* @return 0 if everything went fine. An error code if something went wrong.
**/
int storeHexPreferences(FILE* f)
int storeHexPreferences(FILE* f, HexBookmarkList& source = hexBookmarks)
{
int i;
// Writes the number of bookmarks to save
if (fwrite(&nextBookmark, sizeof(nextBookmark), 1, f) != 1) return 1;
if (fwrite(&source.bookmarkCount, sizeof(source.bookmarkCount), 1, f) != 1) return 1;
for (i=0;i<nextBookmark;i++)
for (i=0;i<source.bookmarkCount;i++)
{
unsigned int len;
// Writes the bookmark address
if (fwrite(&hexBookmarks[i].address, sizeof(hexBookmarks[i].address), 1, f) != 1) return 1;
if (fwrite(&source[i].address, sizeof(source[i].address), 1, f) != 1) return 1;
len = strlen(hexBookmarks[i].description);
len = strlen(source[i].description);
// Writes the length of the bookmark description
if (fwrite(&len, sizeof(len), 1, f) != 1) return 1;
// Writes the actual bookmark description
if (fwrite(hexBookmarks[i].description, 1, len, f) != len) return 1;
if (fwrite(source[i].description, 1, len, f) != len) return 1;
}
// Optional Section 1: Save bookmark shortcut matches
if (numHexBookmarkShortcut)
if (source.shortcutCount)
{
fwrite(&numHexBookmarkShortcut, sizeof(numHexBookmarkShortcut), 1, f);
fwrite(&source.shortcutCount, sizeof(source.shortcutCount), 1, f);
for (int i = 0; i < 10; ++i)
if (hexBookmarkShortcut[i] != -1)
if (source.shortcuts[i] != -1)
{
fwrite(&hexBookmarkShortcut[i], sizeof(hexBookmarkShortcut[i]), 1, f);
fwrite(&source.shortcuts[i], sizeof(source.shortcuts[i]), 1, f);
fwrite(&i, sizeof(i), 1, f);
}
}
@ -163,8 +164,8 @@ int storeHexPreferences(FILE* f)
version of FCEUX, we can only add the extra data to the last of the file
to fix this problem.
*/
for (int i = 0; i < nextBookmark; ++i)
if (fwrite(&hexBookmarks[i].editmode, sizeof(hexBookmarks[i].editmode), 1, f) != 1)
for (int i = 0; i < source.bookmarkCount; ++i)
if (fwrite(&source[i].editmode, sizeof(source[i].editmode), 1, f) != 1)
return 1;
return 0;
@ -360,30 +361,31 @@ int loadDebuggerPreferences(FILE* f)
* Loads HexView preferences from a file
*
* @param f File to write the preferences to
* @param target The target to load the preferences to
* @return 0 if everything went fine. An error code if something went wrong.
**/
int loadHexPreferences(FILE* f)
int loadHexPreferences(FILE* f, HexBookmarkList& target = hexBookmarks)
{
int i;
// Read number of bookmarks
if (fread(&nextBookmark, sizeof(nextBookmark), 1, f) != 1) return 1;
if (nextBookmark >= 64) return 1;
if (fread(&target.bookmarkCount, sizeof(target.bookmarkCount), 1, f) != 1) return 1;
if (target.bookmarkCount >= 64) return 1;
// clean the garbage values
memset(hexBookmarks, 0, sizeof(HexBookmark) * nextBookmark);
memset(&target.bookmarks, 0, sizeof(HexBookmark) * target.bookmarkCount);
for (i=0;i<nextBookmark;i++)
for (i=0;i<target.bookmarkCount;i++)
{
unsigned int len;
// Read address
if (fread(&hexBookmarks[i].address, sizeof(hexBookmarks[i].address), 1, f) != 1) return 1;
if (fread(&target[i].address, sizeof(target[i].address), 1, f) != 1) return 1;
// Read length of description
if (fread(&len, sizeof(len), 1, f) != 1) return 1;
// Read the bookmark description
if (fread(hexBookmarks[i].description, 1, len, f) != len) return 1;
if (fread(target[i].description, 1, len, f) != len) return 1;
}
/* Optional Section 1: read bookmark shortcut matches
@ -392,21 +394,21 @@ int loadHexPreferences(FILE* f)
*/
if (!feof(f))
{
fread(&numHexBookmarkShortcut, sizeof(numHexBookmarkShortcut), 1, f);
fread(&target.shortcutCount, sizeof(target.shortcutCount), 1, f);
unsigned int bookmark_index, shortcut_index;
// read the matching index list of the shortcuts
for (unsigned int i = 0; i < numHexBookmarkShortcut; ++i)
for (unsigned int i = 0; i < target.shortcutCount; ++i)
if (fread(&bookmark_index, sizeof(bookmark_index), 1, f) != EOF && fread(&shortcut_index, sizeof(shortcut_index), 1, f) != EOF)
hexBookmarkShortcut[shortcut_index % 10] = bookmark_index;
target.shortcuts[shortcut_index % 10] = bookmark_index;
else
break;
}
else {
// use the default configruation based on the order of the bookmark list
numHexBookmarkShortcut = nextBookmark > 10 ? 10 : nextBookmark;
for (int i = 0; i < numHexBookmarkShortcut; ++i)
hexBookmarkShortcut[i] = i;
target.shortcutCount = target.bookmarkCount > 10 ? 10 : target.bookmarkCount;
for (int i = 0; i < target.shortcutCount; ++i)
target.shortcuts[i] = i;
}
/*
@ -420,10 +422,10 @@ int loadHexPreferences(FILE* f)
*/
int editmode;
if (!feof(f))
for (int i = 0; i < nextBookmark; i++)
for (int i = 0; i < target.bookmarkCount; i++)
{
if (fread(&editmode, sizeof(editmode), 1, f) != EOF)
hexBookmarks[i].editmode = editmode;
target[i].editmode = editmode;
else break;
}
return 0;
@ -465,7 +467,7 @@ int loadPreferences(const char* romname)
myNumWPs = 0;
break_on_instructions = break_on_cycles = FCEUI_Debugger().badopbreak = false;
break_instructions_limit = break_cycles_limit = 0;
nextBookmark = 0;
hexBookmarks.bookmarkCount = 0;
}
fclose(f);
} else

File diff suppressed because it is too large Load Diff

View File

@ -642,17 +642,28 @@
#define IDC_BOOKMARK_VIEW_TEXT 1110
#define IDC_BOOKMARK_COMBO_VIEW 1112
#define IDC_CHEAT_SHOWGG 1112
#define IDC_RADIO_BOOKMARKIMPORTOPTION_DISCARD 1114
#define IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKOVERWRITE 1115
#define IDC_RADIO_BOOKMARKIMPORTOPTION_BOOKMARKIGNORE 1116
#define BTN_ALLOW_LRUD 1117
#define IDC_RADIO_BOOKMARKIMPORTOPTION_MERGE 1117
#define IDC_PRGROM_EDIT 1118
#define IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTREASSIGN 1118
#define IDC_CHRROM_EDIT 1119
#define BTN_PRESET_SET1 1119
#define IDC_RADIO_BOOKMARKIMPORTOPTION_SHORTCUTKEEP 1119
#define BTN_PRESET_SET2 1120
#define BTN_PRESET_SET3 1121
#define IDC_CHECK_BOOKMARKIMPORTOPTION_CONFIRMEVERYTIMEONCONFLICT 1121
#define BTN_PRESET_IMPORT1 1122
#define IDC_TEXT_BOOKMARKIMPORTOPTION 1122
#define BTN_PRESET_IMPORT2 1123
#define IDC_TEXT_BOOKMARKIMPORTOPTION_BOOKMARK 1123
#define BTN_PRESET_IMPORT3 1124
#define IDC_TEXT_BOOKMARKIMPORTOPTION_SHORTCUT 1124
#define IDC_PRGRAM_EDIT 1125
#define BTN_PRESET_EXPORT1 1125
#define IDC_GROUP_BOOKMARKIMPORTOPTION_SOLVECONFLICT 1125
#define BTN_PRESET_EXPORT2 1126
#define BTN_PRESET_EXPORT3 1127
#define IDC_CHRRAM_EDIT 1128
@ -869,6 +880,10 @@
#define IDC_GAME_GENIE_ADDR 1501
#define MENU_INESHEADEREDITOR 40001
#define MENU_INPUT_BARCODE 40004
#define ID_BOOKMARKS_IMPORT 40005
#define ID_BOOKMARKS_SAVEAS 40006
#define ID_BOOKMARKS_OPTION 40007
#define ID_BOOKMARKS_EXPORT 40008
#define MENU_NETWORK 40040
#define MENU_PALETTE 40041
#define MENU_SOUND 40042
@ -1164,9 +1179,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 309
#define _APS_NEXT_COMMAND_VALUE 40005
#define _APS_NEXT_CONTROL_VALUE 1113
#define _APS_NEXT_RESOURCE_VALUE 311
#define _APS_NEXT_COMMAND_VALUE 40009
#define _APS_NEXT_CONTROL_VALUE 1126
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif