fceux/drivers/win/pref.cpp

281 lines
7.5 KiB
C++

/* FCEUXD SP - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2005 Sebastian Porst
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "debuggersp.h"
#include "memviewsp.h"
#include "common.h"
#include "debugger.h"
#include "../../debug.h"
extern char symbDebugEnabled;
/**
* Stores debugger preferences in a file
*
* @param f File to write the preferences to
* @return 0 if everything went fine. An error code if something went wrong.
**/
int storeDebuggerPreferences(FILE* f)
{
int i;
// Flag that says whether symbolic debugging should be enabled
if (fwrite(&symbDebugEnabled, 1, 1, f) != 1) return 1;
// Write the number of active CPU bookmarks
if (fwrite(&bookmarks, sizeof(unsigned int), 1, f) != 1) return 1;
// Write the addresses of those bookmarks
if (fwrite(bookmarkData, sizeof(unsigned short), bookmarks, f) != bookmarks) return 1;
// Write all breakpoints
for (i=0;i<65;i++)
{
unsigned int len;
// Write the start address of a BP
if (fwrite(&watchpoint[i].address, sizeof(watchpoint[i].address), 1, f) != 1) return 1;
// Write the end address of a BP
if (fwrite(&watchpoint[i].endaddress, sizeof(watchpoint[i].endaddress), 1, f) != 1) return 1;
// Write the flags of a BP
if (fwrite(&watchpoint[i].flags, sizeof(watchpoint[i].flags), 1, f) != 1) return 1;
// Write the length of the BP condition
len = watchpoint[i].condText ? strlen(watchpoint[i].condText) : 0;
if (fwrite(&len, sizeof(len), 1, f) != 1) return 1;
// Write the text of the BP condition
if (len)
{
if (fwrite(watchpoint[i].condText, 1, len, f) != len) return 1;
}
len = watchpoint[i].desc ? strlen(watchpoint[i].desc) : 0;
// Write the length of the BP description
if (fwrite(&len, sizeof(len), 1, f) != 1) return 1;
// Write the actual BP description
if (len)
{
if (fwrite(watchpoint[i].desc, 1, len, f) != len) return 1;
}
}
return 0;
}
/**
* Stores the preferences from the Hex window
*
* @param f File to write the preferences to
* @return 0 if everything went fine. An error code if something went wrong.
**/
int storeHexPreferences(FILE* f)
{
int i;
// Writes the number of bookmarks to save
if (fwrite(&nextBookmark, sizeof(nextBookmark), 1, f) != 1) return 1;
for (i=0;i<nextBookmark;i++)
{
unsigned int len;
// Writes the bookmark address
if (fwrite(&hexBookmarks[i].address, sizeof(hexBookmarks[i].address), 1, f) != 1) return 1;
len = strlen(hexBookmarks[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;
}
return 0;
}
/**
* Stores the debugging preferences to a file name romname.nes.deb
*
* @param romname Name of the ROM
* @return 0 on success or an error code.
**/
int storePreferences(char* romname)
{
FILE* f;
char* filename;
if (!debuggerWasActive)
{
return 0;
}
filename = (char*)malloc(strlen(romname) + 5);
sprintf(filename, "%s.deb", romname);
f = fopen(filename, "wb");
free(filename);
return !f || storeDebuggerPreferences(f) || storeHexPreferences(f);
}
int myNumWPs = 0;
int loadDebugDataFailed = 0;
/**
* Loads debugger preferences from a file
*
* @param f File to write the preferences to
* @return 0 if everything went fine. An error code if something went wrong.
**/
int loadDebuggerPreferences(FILE* f)
{
unsigned int i;
// Read flag that says if symbolic debugging is enabled
if (fread(&symbDebugEnabled, sizeof(symbDebugEnabled), 1, f) != 1) return 1;
// Read the number of CPU bookmarks
if (fread(&bookmarks, sizeof(bookmarks), 1, f) != 1) return 1;
bookmarkData = (unsigned short*)malloc(bookmarks * sizeof(unsigned short));
// Read the offsets of the bookmarks
for (i=0;i<bookmarks;i++)
{
if (fread(&bookmarkData[i], sizeof(bookmarkData[i]), 1, f) != 1) return 1;
}
myNumWPs = 0;
// Read the breakpoints
for (i=0;i<65;i++)
{
uint16 start, end;
uint8 flags;
unsigned int len;
// Read the start address of the BP
if (fread(&start, sizeof(start), 1, f) != 1) return 1;
// Read the end address of the BP
if (fread(&end, sizeof(end), 1, f) != 1) return 1;
// Read the flags of the BP
if (fread(&flags, sizeof(flags), 1, f) != 1) return 1;
// Read the length of the BP description
if (fread(&len, sizeof(len), 1, f) != 1) return 1;
if (len)
{
// Delete eventual older conditions
if (watchpoint[myNumWPs].condText)
free(watchpoint[myNumWPs].condText);
// Read the breakpoint condition
watchpoint[myNumWPs].condText = (char*)malloc(len + 1);
watchpoint[myNumWPs].condText[len] = 0;
if (fread(watchpoint[myNumWPs].condText, 1, len, f) != len) return 1;
// TODO: Check return value
checkCondition(watchpoint[myNumWPs].condText, myNumWPs);
}
// Read length of the BP description
if (fread(&len, sizeof(len), 1, f) != 1) return 1;
if (len)
{
// Delete eventual older description
if (watchpoint[myNumWPs].desc)
free(watchpoint[myNumWPs].desc);
// Read breakpoint description
watchpoint[myNumWPs].desc = (char*)malloc(len + 1);
watchpoint[myNumWPs].desc[len] = 0;
if (fread(watchpoint[myNumWPs].desc, 1, len, f) != len) return 1;
}
// Activate breapoint
if (start || end || flags)
{
watchpoint[myNumWPs].address = start;
watchpoint[myNumWPs].endaddress = end;
watchpoint[myNumWPs].flags = flags;
myNumWPs++;
}
}
return 0;
}
/**
* Loads HexView preferences from a file
*
* @param f File to write the preferences to
* @return 0 if everything went fine. An error code if something went wrong.
**/
int loadHexPreferences(FILE* f)
{
int i;
// Read number of bookmarks
fread(&nextBookmark, sizeof(nextBookmark), 1, f);
for (i=0;i<nextBookmark;i++)
{
unsigned int len;
// Read address
if (fread(&hexBookmarks[i].address, sizeof(hexBookmarks[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;
}
return 0;
}
/**
* Loads the debugging preferences from disk
*
* @param romname Name of the active ROM file
* @return 0 or an error code.
**/
int loadPreferences(char* romname)
{
FILE* f;
// Get the name of the preferences file
char* filename = (char*)malloc(strlen(romname) + 5);
sprintf(filename, "%s.deb", romname);
f = fopen(filename, "rb");
free(filename);
// Attempt to load the preferences
return f ? loadDebuggerPreferences(f) || loadHexPreferences(f) : 0;
}