diff --git a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs index dbfaeb27bc..759ce9647c 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -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(); diff --git a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/LibGambatte.cs b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/LibGambatte.cs index 3dd7414c04..8414b2a9bb 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/LibGambatte.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/LibGambatte.cs @@ -40,11 +40,12 @@ namespace BizHawk.Emulation.Consoles.GB /// Load ROM image. /// /// opaque state pointer - /// Path to rom image file. Typically a .gbc, .gb, or .zip-file (if zip-support is compiled in). + /// the rom data, can be disposed of once this function returns + /// length of romdata in bytes /// ORed combination of LoadFlags. /// 0 on success, negative value on failure. [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); /// /// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer, @@ -215,16 +216,16 @@ namespace BizHawk.Emulation.Consoles.GB /// /// opaque state pointer /// - [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); /// /// Current state slot selected with selectState(). Returns a value between 0 and 9 inclusive. /// /// opaque state pointer /// - [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); /// /// ROM header title of currently loaded ROM image. diff --git a/BizHawk.MultiClient/output/libgambatte.dll b/BizHawk.MultiClient/output/libgambatte.dll index ecc7597419..ad71e22bad 100644 Binary files a/BizHawk.MultiClient/output/libgambatte.dll and b/BizHawk.MultiClient/output/libgambatte.dll differ diff --git a/BizHawk.MultiClient/output/libgambatte.pdb b/BizHawk.MultiClient/output/libgambatte.pdb index 454007c760..609f28d424 100644 Binary files a/BizHawk.MultiClient/output/libgambatte.pdb and b/BizHawk.MultiClient/output/libgambatte.pdb differ diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h index 993899d717..467b22d094 100644 --- a/libgambatte/include/gambatte.h +++ b/libgambatte/include/gambatte.h @@ -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. diff --git a/libgambatte/src/cinterface.cpp b/libgambatte/src/cinterface.cpp index 3d6e4f34d8..7995e03f0d 100644 --- a/libgambatte/src/cinterface.cpp +++ b/libgambatte/src/cinterface.cpp @@ -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; } diff --git a/libgambatte/src/cinterface.h b/libgambatte/src/cinterface.h index b6c1cd66ef..4fbbb44b95 100644 --- a/libgambatte/src/cinterface.h +++ b/libgambatte/src/cinterface.h @@ -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); diff --git a/libgambatte/src/cpu.h b/libgambatte/src/cpu.h index 238e63915e..6b3208a209 100644 --- a/libgambatte/src/cpu.h +++ b/libgambatte/src/cpu.h @@ -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(); } diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp index 9302ebda28..b2fbfd1ae4 100644 --- a/libgambatte/src/gambatte.cpp +++ b/libgambatte/src/gambatte.cpp @@ -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; diff --git a/libgambatte/src/mem/cartridge.cpp b/libgambatte/src/mem/cartridge.cpp index 7b5c765025..05252e28d2 100644 --- a/libgambatte/src/mem/cartridge.cpp +++ b/libgambatte/src/mem/cartridge.cpp @@ -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 rom(newFileInstance(romfile)); +int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) { + //const std::auto_ptr 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(header), sizeof header); + //rom->read(reinterpret_cast(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(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(memptrs.romdata()), (filesize / 0x4000) * 0x4000ul); + //rom->rewind(); + //rom->read(reinterpret_cast(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; diff --git a/libgambatte/src/mem/cartridge.h b/libgambatte/src/mem/cartridge.h index a3b77d7026..b7a8a41b37 100644 --- a/libgambatte/src/mem/cartridge.h +++ b/libgambatte/src/mem/cartridge.h @@ -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(memptrs.romdata() + 0x134); } void setGameGenie(const std::string &codes); }; diff --git a/libgambatte/src/memory.cpp b/libgambatte/src/memory.cpp index c368c8b699..ed3899c519 100644 --- a/libgambatte/src/memory.cpp +++ b/libgambatte/src/memory.cpp @@ -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()); diff --git a/libgambatte/src/memory.h b/libgambatte/src/memory.h index 4fc29e08e5..00bcfdbc14 100644 --- a/libgambatte/src/memory.h +++ b/libgambatte/src/memory.h @@ -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) {