fix up rom loading routines for libgambatte to use memory block directly (and not file)

This commit is contained in:
goyuken 2012-09-09 21:15:54 +00:00
parent 90d1d12086
commit a6caa8680d
13 changed files with 45 additions and 33 deletions

View File

@ -28,6 +28,12 @@ namespace BizHawk.Emulation.Consoles.GB
public Gameboy(byte[] romdata)
{
GambatteState = LibGambatte.gambatte_create();
if (GambatteState == IntPtr.Zero)
throw new Exception("gambatte_create() returned null???");
/*
// use temp file until we hack up the libgambatte api to take data directly
using (FileStream fs = new FileStream("gambattetmp.gb", FileMode.OpenOrCreate, FileAccess.Write))
@ -35,13 +41,13 @@ namespace BizHawk.Emulation.Consoles.GB
fs.Write(romdata, 0, romdata.Length);
}
GambatteState = LibGambatte.gambatte_create();
if (GambatteState == IntPtr.Zero)
throw new Exception("gambatte_create() returned null???");
if (LibGambatte.gambatte_load(GambatteState, "gambattetmp.gb", 0) != 0)
throw new Exception("gambatte_load() returned non-zero (is this not a gb or gbc rom?)");
*/
if (LibGambatte.gambatte_load(GambatteState, romdata, (uint)romdata.Length, 0) != 0)
throw new Exception("gambatte_load() returned non-zero (is this not a gb or gbc rom?)");
InitSound();

View File

@ -40,11 +40,12 @@ namespace BizHawk.Emulation.Consoles.GB
/// Load ROM image.
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="filename">Path to rom image file. Typically a .gbc, .gb, or .zip-file (if zip-support is compiled in).</param>
/// <param name="romdata">the rom data, can be disposed of once this function returns</param>
/// <param name="length">length of romdata in bytes</param>
/// <param name="flags">ORed combination of LoadFlags.</param>
/// <returns>0 on success, negative value on failure.</returns>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_load(IntPtr core, string filename, LoadFlags flags);
public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, LoadFlags flags);
/// <summary>
/// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
@ -215,16 +216,16 @@ namespace BizHawk.Emulation.Consoles.GB
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="n"></param>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_selectstate(IntPtr core, int n);
//[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
//public static extern void gambatte_selectstate(IntPtr core, int n);
/// <summary>
/// Current state slot selected with selectState(). Returns a value between 0 and 9 inclusive.
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <returns></returns>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_currentstate(IntPtr core);
//[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
//public static extern int gambatte_currentstate(IntPtr core);
/// <summary>
/// ROM header title of currently loaded ROM image.

View File

@ -44,7 +44,7 @@ public:
* @param flags ORed combination of LoadFlags.
* @return 0 on success, negative value on failure.
*/
int load(const std::string &romfile, unsigned flags = 0);
int load(const char *romfiledata, unsigned romfilelength, unsigned flags = 0);
/** Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
* or until a video frame has been drawn.

View File

@ -17,10 +17,10 @@ __declspec(dllexport) void gambatte_destroy(void *core)
delete g;
}
__declspec(dllexport) int gambatte_load(void *core, const char *filename, unsigned flags)
__declspec(dllexport) int gambatte_load(void *core, const char *romfiledata, unsigned romfilelength, unsigned flags)
{
GB *g = (GB *) core;
int ret = g->load(std::string(filename), flags);
int ret = g->load(romfiledata, romfilelength, flags);
return ret;
}

View File

@ -8,7 +8,7 @@ extern "C"
__declspec(dllexport) void *gambatte_create();
__declspec(dllexport) void gambatte_destroy(void *core);
__declspec(dllexport) int gambatte_load(void *core, const char *filename, unsigned flags);
__declspec(dllexport) int gambatte_load(void *core, const char *romfiledata, unsigned romfilelength, unsigned flags);
__declspec(dllexport) long gambatte_runfor(void *core, unsigned long *videobuf, int pitch, short *soundbuf, unsigned *samples);

View File

@ -74,8 +74,8 @@ public:
memory.setOsdElement(osdElement);
}
int load(const std::string &romfile, bool forceDmg, bool multicartCompat) {
return memory.loadROM(romfile, forceDmg, multicartCompat);
int load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
return memory.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat);
}
bool loaded() const { return memory.loaded(); }

View File

@ -88,11 +88,11 @@ void GB::setSaveDir(const std::string &sdir) {
p_->cpu.setSaveDir(sdir);
}
int GB::load(const std::string &romfile, const unsigned flags) {
int GB::load(const char *romfiledata, unsigned romfilelength, const unsigned flags) {
if (p_->cpu.loaded())
p_->cpu.saveSavedata();
const int failed = p_->cpu.load(romfile, flags & FORCE_DMG, flags & MULTICART_COMPAT);
const int failed = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT);
if (!failed) {
SaveState state;

View File

@ -504,11 +504,11 @@ static unsigned pow2ceil(unsigned n) {
return n;
}
int Cartridge::loadROM(const std::string &romfile, const bool forceDmg, const bool multicartCompat) {
const std::auto_ptr<File> rom(newFileInstance(romfile));
int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
//const std::auto_ptr<File> rom(newFileInstance(romfile));
if (rom->fail())
return -1;
//if (rom->fail())
// return -1;
unsigned rambanks = 1;
unsigned rombanks = 2;
@ -517,7 +517,11 @@ int Cartridge::loadROM(const std::string &romfile, const bool forceDmg, const bo
{
unsigned char header[0x150];
rom->read(reinterpret_cast<char*>(header), sizeof header);
//rom->read(reinterpret_cast<char*>(header), sizeof header);
if (romfilelength >= sizeof header)
std::memcpy(header, romfiledata, sizeof header);
else
return -1;
switch (header[0x0147]) {
case 0x00: std::puts("Plain ROM loaded."); type = PLAIN; break;
@ -596,7 +600,7 @@ int Cartridge::loadROM(const std::string &romfile, const bool forceDmg, const bo
std::printf("rambanks: %u\n", rambanks);
const std::size_t filesize = rom->size();
const std::size_t filesize = romfilelength; //rom->size();
rombanks = std::max(pow2ceil(filesize / 0x4000), 2u);
std::printf("rombanks: %u\n", static_cast<unsigned>(filesize / 0x4000));
@ -606,15 +610,16 @@ int Cartridge::loadROM(const std::string &romfile, const bool forceDmg, const bo
memptrs.reset(rombanks, rambanks, cgb ? 8 : 2);
rtc.set(false, 0);
rom->rewind();
rom->read(reinterpret_cast<char*>(memptrs.romdata()), (filesize / 0x4000) * 0x4000ul);
//rom->rewind();
//rom->read(reinterpret_cast<char*>(memptrs.romdata()), (filesize / 0x4000) * 0x4000ul);
std::memcpy(memptrs.romdata(), romfiledata, (filesize / 0x4000) * 0x4000ul);
std::memset(memptrs.romdata() + (filesize / 0x4000) * 0x4000ul, 0xFF, (rombanks - filesize / 0x4000) * 0x4000ul);
enforce8bit(memptrs.romdata(), rombanks * 0x4000ul);
if (rom->fail())
return -1;
//if (rom->fail())
// return -1;
defaultSaveBasePath = stripExtension(romfile);
defaultSaveBasePath = stripExtension("fixmefixme.gb"); //(romfile);
switch (type) {
case PLAIN: mbc.reset(new Mbc0(memptrs)); break;

View File

@ -86,7 +86,7 @@ public:
void saveSavedata();
const std::string saveBasePath() const;
void setSaveDir(const std::string &dir);
int loadROM(const std::string &romfile, bool forceDmg, bool multicartCompat);
int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
const char * romTitle() const { return reinterpret_cast<const char *>(memptrs.romdata() + 0x134); }
void setGameGenie(const std::string &codes);
};

View File

@ -983,8 +983,8 @@ void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsig
ioamhram[P - 0xFE00] = data;
}
int Memory::loadROM(const std::string &romfile, const bool forceDmg, const bool multicartCompat) {
if (const int fail = cart.loadROM(romfile, forceDmg, multicartCompat))
int Memory::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
if (const int fail = cart.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
return fail;
sound.init(cart.isCgb());

View File

@ -128,7 +128,7 @@ public:
unsigned long event(unsigned long cycleCounter);
unsigned long resetCounters(unsigned long cycleCounter);
int loadROM(const std::string &romfile, bool forceDmg, bool multicartCompat);
int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
void setSaveDir(const std::string &dir) { cart.setSaveDir(dir); }
void setInputGetter(InputGetter *getInput) {