rough in some snes9x stuff. not working yet

This commit is contained in:
nattthebear 2017-05-21 17:43:43 -04:00
parent dc6646a020
commit 7739b9dc80
6 changed files with 128 additions and 16 deletions

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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