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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg, (short)idx);
|
||||
|
|
|
@ -3,18 +3,48 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using BizHawk.Common.BizInvoke;
|
||||
|
||||
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;
|
||||
|
||||
[DllImport(DllName, CallingConvention = CC)]
|
||||
public static extern bool debug_init(byte[] data, int length);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CC)]
|
||||
public static extern void debug_advance(int[] data);
|
||||
[BizImport(CC)]
|
||||
public abstract void biz_set_sound_channels(int channels);
|
||||
[BizImport(CC)]
|
||||
public abstract void biz_set_layers(int layers);
|
||||
[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 BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Waterbox;
|
||||
using BizHawk.Common.BizInvoke;
|
||||
|
||||
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))]
|
||||
public class Snes9x : IEmulator, IVideoProvider, ISoundProvider
|
||||
{
|
||||
private LibSnes9x _core;
|
||||
private PeRunner _exe;
|
||||
|
||||
|
||||
[CoreConstructor("SNES")]
|
||||
public Snes9x(CoreComm comm, byte[] rom)
|
||||
{
|
||||
if (!LibSnes9x.debug_init(rom, rom.Length))
|
||||
throw new Exception();
|
||||
|
||||
ServiceProvider = new BasicServiceProvider(this);
|
||||
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
|
||||
|
@ -26,8 +50,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
|||
|
||||
#endregion
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_exe.Dispose();
|
||||
_exe = null;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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; }
|
||||
|
@ -52,13 +86,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
|||
|
||||
#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];
|
||||
public int[] GetVideoBuffer() { return _vbuff; }
|
||||
public int VirtualWidth
|
||||
{ get { return (int)(BufferWidth * 1.146); ; } }
|
||||
public int VirtualHeight { get { return BufferHeight; } }
|
||||
public int BufferWidth { get { return 256; } }
|
||||
public int BufferHeight { get { return 224; } }
|
||||
public int BufferWidth { get; private set; } = 256;
|
||||
public int BufferHeight { get; private set; } = 224;
|
||||
public int BackgroundColor { get { return unchecked((int)0xff000000); } }
|
||||
|
||||
public int VsyncNumerator
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// mark an entry point or callback pointer
|
||||
#define ECL_ENTRY
|
||||
// mark a visible symbol
|
||||
|
@ -22,4 +26,8 @@ void *alloc_invisible(size_t size);
|
|||
// send a debug string somewhere, bypassing stdio
|
||||
void _debug_puts(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#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 \
|
||||
-std=c99 -fomit-frame-pointer -fvisibility=hidden \
|
||||
-DLSB_FIRST -DUSE_32BPP_RENDERING -DINLINE=static\ __inline__ \
|
||||
-O2#-mcmodel=large
|
||||
-O3#-mcmodel=large
|
||||
|
||||
TARGET = gpgx.exe
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 737caf908be47b868bf58080f87ce9f3592fce07
|
||||
Subproject commit 3a358804d34b9ed5b4bedd9266bcebf255d72cfe
|
Loading…
Reference in New Issue