preliminary C api for libgambatte, plus pinvoke bindings
i'm a bit out of my league on this one, but that's ok
This commit is contained in:
parent
285b9581f2
commit
3061abbc4b
|
@ -112,6 +112,7 @@
|
||||||
<Compile Include="Consoles\Coleco\VDP.Tables.cs" />
|
<Compile Include="Consoles\Coleco\VDP.Tables.cs" />
|
||||||
<Compile Include="Consoles\GB\Graphics.cs" />
|
<Compile Include="Consoles\GB\Graphics.cs" />
|
||||||
<Compile Include="Consoles\GB\Input.cs" />
|
<Compile Include="Consoles\GB\Input.cs" />
|
||||||
|
<Compile Include="Consoles\GB\LibGambatte.cs" />
|
||||||
<Compile Include="Consoles\GB\MemoryMap.cs" />
|
<Compile Include="Consoles\GB\MemoryMap.cs" />
|
||||||
<Compile Include="Consoles\GB\GB.cs" />
|
<Compile Include="Consoles\GB\GB.cs" />
|
||||||
<Compile Include="Consoles\Intellivision\Cartridge.cs" />
|
<Compile Include="Consoles\Intellivision\Cartridge.cs" />
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Consoles.GB
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// static bindings into libgambatte.dll
|
||||||
|
/// </summary>
|
||||||
|
public static class LibGambatte
|
||||||
|
{
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr gambatte_create();
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_destroy(IntPtr core);
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum LoadFlags : uint
|
||||||
|
{
|
||||||
|
/// <summary>Treat the ROM as not having CGB support regardless of what its header advertises</summary>
|
||||||
|
FORCE_DMG = 1,
|
||||||
|
/// <summary>Use GBA intial CPU register values when in CGB mode.</summary>
|
||||||
|
GBA_CGB = 2,
|
||||||
|
/// <summary>Use heuristics to detect and support some multicart MBCs disguised as MBC1.</summary>
|
||||||
|
MULTICART_COMPAT = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gambatte_load(IntPtr core, string filename, LoadFlags flags);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern long gambatte_runfor(IntPtr core, uint[] videobuf, int pitch, short[] soundbuf, ref uint samples);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_reset(IntPtr core);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_setdmgpalettecolor(IntPtr core, uint palnum, uint colornum, uint rgb32);
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum Buttons
|
||||||
|
{
|
||||||
|
A = 0x01,
|
||||||
|
B = 0x02,
|
||||||
|
SELECT = 0x04,
|
||||||
|
START = 0x08,
|
||||||
|
RIGHT = 0x10,
|
||||||
|
LEFT = 0x20,
|
||||||
|
UP = 0x40,
|
||||||
|
DOWN = 0x80
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_setinputgetter(IntPtr core, Func<Buttons> getinput);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_setsavedir(IntPtr core, string sdir);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gambatte_iscgb(IntPtr core);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gambatte_isloaded(IntPtr core);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_savesavedate(IntPtr core);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gambatte_savestate(IntPtr core, uint[] videobuf, int pitch);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gambatte_loadstate(IntPtr core);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gambatte_savestate_file(IntPtr core, uint[] videobuf, int pitch, string filepath);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int gambatte_loadstate_file(IntPtr core, string filepath);
|
||||||
|
|
||||||
|
[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 int gambatte_currentstate(IntPtr core);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern string gambatte_romtitle(IntPtr core);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_setgamegenie(IntPtr core, string codes);
|
||||||
|
|
||||||
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void gambatte_setgameshark(IntPtr core, string codes);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,6 +79,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\bitmap_font.cpp" />
|
<ClCompile Include="src\bitmap_font.cpp" />
|
||||||
|
<ClCompile Include="src\cinterface.cpp" />
|
||||||
<ClCompile Include="src\cpu.cpp" />
|
<ClCompile Include="src\cpu.cpp" />
|
||||||
<ClCompile Include="src\file\file.cpp" />
|
<ClCompile Include="src\file\file.cpp" />
|
||||||
<ClCompile Include="src\gambatte.cpp" />
|
<ClCompile Include="src\gambatte.cpp" />
|
||||||
|
@ -112,6 +113,7 @@
|
||||||
<ClInclude Include="include\gbint.h" />
|
<ClInclude Include="include\gbint.h" />
|
||||||
<ClInclude Include="include\inputgetter.h" />
|
<ClInclude Include="include\inputgetter.h" />
|
||||||
<ClInclude Include="src\bitmap_font.h" />
|
<ClInclude Include="src\bitmap_font.h" />
|
||||||
|
<ClInclude Include="src\cinterface.h" />
|
||||||
<ClInclude Include="src\counterdef.h" />
|
<ClInclude Include="src\counterdef.h" />
|
||||||
<ClInclude Include="src\cpu.h" />
|
<ClInclude Include="src\cpu.h" />
|
||||||
<ClInclude Include="src\file\file.h" />
|
<ClInclude Include="src\file\file.h" />
|
||||||
|
|
|
@ -99,6 +99,9 @@
|
||||||
<ClCompile Include="src\video\sprite_mapper.cpp">
|
<ClCompile Include="src\video\sprite_mapper.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\cinterface.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\statesaver.h">
|
<ClInclude Include="src\statesaver.h">
|
||||||
|
@ -218,5 +221,8 @@
|
||||||
<ClInclude Include="include\inputgetter.h">
|
<ClInclude Include="include\inputgetter.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\cinterface.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,148 @@
|
||||||
|
#include "cinterface.h"
|
||||||
|
#include "gambatte.h"
|
||||||
|
|
||||||
|
using namespace gambatte;
|
||||||
|
|
||||||
|
|
||||||
|
__declspec(dllexport) void *gambatte_create()
|
||||||
|
{
|
||||||
|
GB *g = new GB();
|
||||||
|
return (void *) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_destroy(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
delete g;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_load(void *core, const char *filename, unsigned flags)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
int ret = g->load(std::string(filename), flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) long gambatte_runfor(void *core, unsigned long *videobuf, int pitch, short *soundbuf, unsigned *samples)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
unsigned sampv = *samples;
|
||||||
|
long ret = g->runFor(videobuf, pitch, (unsigned long *) soundbuf, sampv);
|
||||||
|
*samples = sampv;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_reset(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setdmgpalettecolor(void *core, unsigned palnum, unsigned colornum, unsigned rgb32)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->setDmgPaletteColor(palnum, colornum, rgb32);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CInputGetter: public InputGetter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
unsigned (*inputfunc)(void);
|
||||||
|
unsigned operator()()
|
||||||
|
{
|
||||||
|
return inputfunc ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setinputgetter(void *core, unsigned (*getinput)(void))
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
CInputGetter *cig = new CInputGetter();
|
||||||
|
cig->inputfunc = getinput;
|
||||||
|
// how do i manage the lifetime of cig?
|
||||||
|
g->setInputGetter(cig);
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setsavedir(void *core, const char *sdir)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->setSaveDir(std::string(sdir));
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_iscgb(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
return g->isCgb();
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_isloaded(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
return g->isLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_savesavedate(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->saveSavedata();
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_savestate(void *core, const unsigned long *videobuf, int pitch)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
return g->saveState(videobuf, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_loadstate(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
return g->loadState();
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_savestate_file(void *core, const unsigned long *videobuf, int pitch, const char *filepath)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
return g->saveState(videobuf, pitch, std::string(filepath));
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_loadstate_file(void *core, const char *filepath)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
return g->loadState(std::string(filepath));
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_selectstate(void *core, int n)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->selectState(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_currentstate(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
return g->currentState();
|
||||||
|
}
|
||||||
|
|
||||||
|
static char horriblebuff[64];
|
||||||
|
__declspec(dllexport) const char *gambatte_romtitle(void *core)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
const char *s = g->romTitle().c_str();
|
||||||
|
std::strncpy(horriblebuff, s, 63);
|
||||||
|
horriblebuff[63] = 0;
|
||||||
|
return horriblebuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setgamegenie(void *core, const char *codes)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->setGameGenie(std::string(codes));
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setgameshark(void *core, const char *codes)
|
||||||
|
{
|
||||||
|
GB *g = (GB *) core;
|
||||||
|
g->setGameShark(std::string(codes));
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef CINTERFACE_H
|
||||||
|
#define CINTERFACE_H
|
||||||
|
|
||||||
|
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) long gambatte_runfor(void *core, unsigned long *videobuf, int pitch, short *soundbuf, unsigned *samples);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_reset(void *core);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setdmgpalettecolor(void *core, unsigned palnum, unsigned colornum, unsigned rgb32);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setinputgetter(void *core, unsigned (*getinput)(void));
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setsavedir(void *core, const char *sdir);
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_iscgb(void *core);
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_isloaded(void *core);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_savesavedate(void *core);
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_savestate(void *core, const unsigned long *videobuf, int pitch);
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_loadstate(void *core);
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_savestate_file(void *core, const unsigned long *videobuf, int pitch, const char *filepath);
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_loadstate_file(void *core, const char *filepath);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_selectstate(void *core, int n);
|
||||||
|
|
||||||
|
__declspec(dllexport) int gambatte_currentstate(void *core);
|
||||||
|
|
||||||
|
__declspec(dllexport) const char *gambatte_romtitle(void *core);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setgamegenie(void *core, const char *codes);
|
||||||
|
|
||||||
|
__declspec(dllexport) void gambatte_setgameshark(void *core, const char *codes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue