rough in some snes9x stuff. not working yet
This commit is contained in:
parent
dc6646a020
commit
7739b9dc80
|
@ -474,6 +474,18 @@ namespace BizHawk.Common.BizInvoke
|
||||||
return typeof(IntPtr);
|
return typeof(IntPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type.IsClass)
|
||||||
|
{
|
||||||
|
// non ref of class can just be passed as pointer
|
||||||
|
var loc = il.DeclareLocal(type, true);
|
||||||
|
il.Emit(OpCodes.Ldarg, (short)idx);
|
||||||
|
il.Emit(OpCodes.Dup);
|
||||||
|
il.Emit(OpCodes.Stloc, loc);
|
||||||
|
il.Emit(OpCodes.Conv_I);
|
||||||
|
|
||||||
|
return typeof(IntPtr);
|
||||||
|
}
|
||||||
|
|
||||||
if (type.IsPrimitive || type.IsEnum)
|
if (type.IsPrimitive || type.IsEnum)
|
||||||
{
|
{
|
||||||
il.Emit(OpCodes.Ldarg, (short)idx);
|
il.Emit(OpCodes.Ldarg, (short)idx);
|
||||||
|
|
|
@ -3,18 +3,48 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using BizHawk.Common.BizInvoke;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
||||||
{
|
{
|
||||||
public class LibSnes9x
|
public abstract class LibSnes9x
|
||||||
{
|
{
|
||||||
const string DllName = "libbizsnes.dll";
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public class memory_area
|
||||||
|
{
|
||||||
|
public IntPtr ptr;
|
||||||
|
public int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public class frame_info
|
||||||
|
{
|
||||||
|
public IntPtr ptr;
|
||||||
|
public int pitch;
|
||||||
|
public int width;
|
||||||
|
public int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const CallingConvention CC = CallingConvention.Cdecl;
|
const CallingConvention CC = CallingConvention.Cdecl;
|
||||||
|
|
||||||
[DllImport(DllName, CallingConvention = CC)]
|
[BizImport(CC)]
|
||||||
public static extern bool debug_init(byte[] data, int length);
|
public abstract void biz_set_sound_channels(int channels);
|
||||||
|
[BizImport(CC)]
|
||||||
[DllImport(DllName, CallingConvention = CC)]
|
public abstract void biz_set_layers(int layers);
|
||||||
public static extern void debug_advance(int[] data);
|
[BizImport(CC)]
|
||||||
|
public abstract void biz_soft_reset();
|
||||||
|
[BizImport(CC)]
|
||||||
|
public abstract void biz_set_port_devices(uint left, uint right);
|
||||||
|
[BizImport(CC)]
|
||||||
|
public abstract bool biz_load_rom(byte[] data, int size);
|
||||||
|
[BizImport(CC)]
|
||||||
|
public abstract bool biz_init();
|
||||||
|
[BizImport(CC)]
|
||||||
|
public abstract void biz_run([In, Out] frame_info frame);
|
||||||
|
[BizImport(CC)]
|
||||||
|
public abstract bool biz_is_ntsc();
|
||||||
|
[BizImport(CC, Compatibility = true)]
|
||||||
|
public abstract void biz_get_memory_area(int which, [In, Out] memory_area mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,44 @@
|
||||||
using System;
|
using System;
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
|
using BizHawk.Emulation.Cores.Waterbox;
|
||||||
|
using BizHawk.Common.BizInvoke;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
||||||
{
|
{
|
||||||
[CoreAttributes("Snes9x", "FIXME", true, false, "5e0319ab3ef9611250efb18255186d0dc0d7e125", "https://github.com/snes9xgit/snes9x", true)]
|
[CoreAttributes("Snes9x", "FIXME", true, false, "5e0319ab3ef9611250efb18255186d0dc0d7e125", "https://github.com/snes9xgit/snes9x", false)]
|
||||||
[ServiceNotApplicable(typeof(IDriveLight))]
|
[ServiceNotApplicable(typeof(IDriveLight))]
|
||||||
public class Snes9x : IEmulator, IVideoProvider, ISoundProvider
|
public class Snes9x : IEmulator, IVideoProvider, ISoundProvider
|
||||||
{
|
{
|
||||||
|
private LibSnes9x _core;
|
||||||
|
private PeRunner _exe;
|
||||||
|
|
||||||
|
|
||||||
[CoreConstructor("SNES")]
|
[CoreConstructor("SNES")]
|
||||||
public Snes9x(CoreComm comm, byte[] rom)
|
public Snes9x(CoreComm comm, byte[] rom)
|
||||||
{
|
{
|
||||||
if (!LibSnes9x.debug_init(rom, rom.Length))
|
|
||||||
throw new Exception();
|
|
||||||
|
|
||||||
ServiceProvider = new BasicServiceProvider(this);
|
ServiceProvider = new BasicServiceProvider(this);
|
||||||
CoreComm = comm;
|
CoreComm = comm;
|
||||||
|
|
||||||
|
_exe = new PeRunner(comm.CoreFileProvider.DllPath(), "snes9x.exe", 20 * 1024 * 1024, 65536, 65536);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_core = BizInvoker.GetInvoker<LibSnes9x>(_exe, _exe);
|
||||||
|
//Console.WriteLine(_exe.Resolve("biz_init"));
|
||||||
|
//System.Diagnostics.Debugger.Break();
|
||||||
|
if (!_core.biz_init())
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Init() failed");
|
||||||
|
}
|
||||||
|
if (!_core.biz_load_rom(rom, rom.Length))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("LoadRom() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region controller
|
#region controller
|
||||||
|
@ -26,8 +50,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private bool _disposed = false;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
if (!_disposed)
|
||||||
|
{
|
||||||
|
_exe.Dispose();
|
||||||
|
_exe = null;
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEmulatorServiceProvider ServiceProvider { get; private set; }
|
public IEmulatorServiceProvider ServiceProvider { get; private set; }
|
||||||
|
@ -35,8 +67,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
||||||
public void FrameAdvance(IController controller, bool render, bool rendersound = true)
|
public void FrameAdvance(IController controller, bool render, bool rendersound = true)
|
||||||
{
|
{
|
||||||
Frame++;
|
Frame++;
|
||||||
|
LibSnes9x.frame_info frame = new LibSnes9x.frame_info();
|
||||||
|
|
||||||
LibSnes9x.debug_advance(_vbuff);
|
_core.biz_run(frame);
|
||||||
|
Blit(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Frame { get; private set; }
|
public int Frame { get; private set; }
|
||||||
|
@ -52,13 +86,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
||||||
|
|
||||||
#region IVideoProvider
|
#region IVideoProvider
|
||||||
|
|
||||||
|
private unsafe void Blit(LibSnes9x.frame_info frame)
|
||||||
|
{
|
||||||
|
BufferWidth = frame.width;
|
||||||
|
BufferHeight = frame.height;
|
||||||
|
|
||||||
|
int vinc = frame.pitch - frame.width;
|
||||||
|
|
||||||
|
ushort* src = (ushort*)frame.ptr;
|
||||||
|
fixed (int* _dst = _vbuff)
|
||||||
|
{
|
||||||
|
byte* dst = (byte*)_dst;
|
||||||
|
|
||||||
|
for (int j = 0; j < frame.height; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < frame.width; i++)
|
||||||
|
{
|
||||||
|
var c = *src++;
|
||||||
|
|
||||||
|
*dst++ = (byte)(c << 3 & 0xf8 | c >> 2 & 7);
|
||||||
|
*dst++ = (byte)(c >> 3 & 0xfa | c >> 9 & 3);
|
||||||
|
*dst++ = (byte)(c >> 8 & 0xf8 | c >> 13 & 7);
|
||||||
|
*dst++ = 0xff;
|
||||||
|
}
|
||||||
|
src += vinc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int[] _vbuff = new int[512 * 480];
|
private int[] _vbuff = new int[512 * 480];
|
||||||
public int[] GetVideoBuffer() { return _vbuff; }
|
public int[] GetVideoBuffer() { return _vbuff; }
|
||||||
public int VirtualWidth
|
public int VirtualWidth
|
||||||
{ get { return (int)(BufferWidth * 1.146); ; } }
|
{ get { return (int)(BufferWidth * 1.146); ; } }
|
||||||
public int VirtualHeight { get { return BufferHeight; } }
|
public int VirtualHeight { get { return BufferHeight; } }
|
||||||
public int BufferWidth { get { return 256; } }
|
public int BufferWidth { get; private set; } = 256;
|
||||||
public int BufferHeight { get { return 224; } }
|
public int BufferHeight { get; private set; } = 224;
|
||||||
public int BackgroundColor { get { return unchecked((int)0xff000000); } }
|
public int BackgroundColor { get { return unchecked((int)0xff000000); } }
|
||||||
|
|
||||||
public int VsyncNumerator
|
public int VsyncNumerator
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
// mark an entry point or callback pointer
|
// mark an entry point or callback pointer
|
||||||
#define ECL_ENTRY
|
#define ECL_ENTRY
|
||||||
// mark a visible symbol
|
// mark a visible symbol
|
||||||
|
@ -22,4 +26,8 @@ void *alloc_invisible(size_t size);
|
||||||
// send a debug string somewhere, bypassing stdio
|
// send a debug string somewhere, bypassing stdio
|
||||||
void _debug_puts(const char *);
|
void _debug_puts(const char *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,7 +6,7 @@ CCFLAGS:=-Icore -Iutil -Icore/m68k -Icore/z80 -Icore/input_hw \
|
||||||
-Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \
|
-Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \
|
||||||
-std=c99 -fomit-frame-pointer -fvisibility=hidden \
|
-std=c99 -fomit-frame-pointer -fvisibility=hidden \
|
||||||
-DLSB_FIRST -DUSE_32BPP_RENDERING -DINLINE=static\ __inline__ \
|
-DLSB_FIRST -DUSE_32BPP_RENDERING -DINLINE=static\ __inline__ \
|
||||||
-O2#-mcmodel=large
|
-O3#-mcmodel=large
|
||||||
|
|
||||||
TARGET = gpgx.exe
|
TARGET = gpgx.exe
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 737caf908be47b868bf58080f87ce9f3592fce07
|
Subproject commit 3a358804d34b9ed5b4bedd9266bcebf255d72cfe
|
Loading…
Reference in New Issue