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) 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 // 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)) 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); 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) 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?)"); 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(); InitSound();

View File

@ -40,11 +40,12 @@ namespace BizHawk.Emulation.Consoles.GB
/// Load ROM image. /// Load ROM image.
/// </summary> /// </summary>
/// <param name="core">opaque state pointer</param> /// <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> /// <param name="flags">ORed combination of LoadFlags.</param>
/// <returns>0 on success, negative value on failure.</returns> /// <returns>0 on success, negative value on failure.</returns>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] [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> /// <summary>
/// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer, /// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
@ -215,16 +216,16 @@ namespace BizHawk.Emulation.Consoles.GB
/// </summary> /// </summary>
/// <param name="core">opaque state pointer</param> /// <param name="core">opaque state pointer</param>
/// <param name="n"></param> /// <param name="n"></param>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] //[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_selectstate(IntPtr core, int n); //public static extern void gambatte_selectstate(IntPtr core, int n);
/// <summary> /// <summary>
/// Current state slot selected with selectState(). Returns a value between 0 and 9 inclusive. /// Current state slot selected with selectState(). Returns a value between 0 and 9 inclusive.
/// </summary> /// </summary>
/// <param name="core">opaque state pointer</param> /// <param name="core">opaque state pointer</param>
/// <returns></returns> /// <returns></returns>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] //[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_currentstate(IntPtr core); //public static extern int gambatte_currentstate(IntPtr core);
/// <summary> /// <summary>
/// ROM header title of currently loaded ROM image. /// ROM header title of currently loaded ROM image.

View File

@ -44,7 +44,7 @@ public:
* @param flags ORed combination of LoadFlags. * @param flags ORed combination of LoadFlags.
* @return 0 on success, negative value on failure. * @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, /** Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
* or until a video frame has been drawn. * or until a video frame has been drawn.

View File

@ -17,10 +17,10 @@ __declspec(dllexport) void gambatte_destroy(void *core)
delete g; 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; GB *g = (GB *) core;
int ret = g->load(std::string(filename), flags); int ret = g->load(romfiledata, romfilelength, flags);
return ret; return ret;
} }

View File

@ -8,7 +8,7 @@ extern "C"
__declspec(dllexport) void *gambatte_create(); __declspec(dllexport) void *gambatte_create();
__declspec(dllexport) void gambatte_destroy(void *core); __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); __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); memory.setOsdElement(osdElement);
} }
int load(const std::string &romfile, bool forceDmg, bool multicartCompat) { int load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
return memory.loadROM(romfile, forceDmg, multicartCompat); return memory.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat);
} }
bool loaded() const { return memory.loaded(); } bool loaded() const { return memory.loaded(); }

View File

@ -88,11 +88,11 @@ void GB::setSaveDir(const std::string &sdir) {
p_->cpu.setSaveDir(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()) if (p_->cpu.loaded())
p_->cpu.saveSavedata(); 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) { if (!failed) {
SaveState state; SaveState state;

View File

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

View File

@ -86,7 +86,7 @@ public:
void saveSavedata(); void saveSavedata();
const std::string saveBasePath() const; const std::string saveBasePath() const;
void setSaveDir(const std::string &dir); 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); } const char * romTitle() const { return reinterpret_cast<const char *>(memptrs.romdata() + 0x134); }
void setGameGenie(const std::string &codes); 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; ioamhram[P - 0xFE00] = data;
} }
int Memory::loadROM(const std::string &romfile, const bool forceDmg, const bool multicartCompat) { int Memory::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
if (const int fail = cart.loadROM(romfile, forceDmg, multicartCompat)) if (const int fail = cart.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
return fail; return fail;
sound.init(cart.isCgb()); sound.init(cart.isCgb());

View File

@ -128,7 +128,7 @@ public:
unsigned long event(unsigned long cycleCounter); unsigned long event(unsigned long cycleCounter);
unsigned long resetCounters(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 setSaveDir(const std::string &dir) { cart.setSaveDir(dir); }
void setInputGetter(InputGetter *getInput) { void setInputGetter(InputGetter *getInput) {