nothing to see here for now

This commit is contained in:
goyuken 2014-01-05 05:23:44 +00:00
parent 5fa18dbb3e
commit 54b9c826cf
5 changed files with 361 additions and 2 deletions

View File

@ -212,7 +212,9 @@ namespace BizHawk.Emulation.Common
{
IsLagFrame = true;
Frame++;
nsamprecv = 0;
retro.retro_run();
Console.WriteLine("[{0}]", nsamprecv);
}
public int Frame { get; private set; }
@ -406,8 +408,13 @@ namespace BizHawk.Emulation.Common
short[] sampbuff = new short[0];
// debug
int nsamprecv = 0;
void SetupResampler(double fps, double sps)
{
Console.WriteLine("FPS {0} SPS {1}", fps, sps);
// todo: more precise?
uint spsnum = (uint)sps * 1000;
uint spsden = (uint)1000;
@ -418,6 +425,7 @@ namespace BizHawk.Emulation.Common
void retro_audio_sample(short left, short right)
{
resampler.EnqueueSample(left, right);
nsamprecv++;
}
uint retro_audio_sample_batch(IntPtr data, uint frames)
@ -426,6 +434,7 @@ namespace BizHawk.Emulation.Common
sampbuff = new short[frames * 2];
Marshal.Copy(data, sampbuff, 0, (int)(frames * 2));
resampler.EnqueueSamples(sampbuff, (int)frames);
nsamprecv += (int)frames;
// what is the return from this used for?
return frames;
}

View File

@ -0,0 +1,184 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
{
public static class LibQuickNES
{
public const string dllname = "libquicknes.dll";
/// <summary>
/// create a new quicknes context
/// </summary>
/// <returns>NULL on failure</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_new();
/// <summary>
/// destroy a quicknes context
/// </summary>
/// <param name="e">context previously returned from qn_new()</param>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern void qn_delete(IntPtr e);
/// <summary>
/// load an ines file
/// </summary>
/// <param name="e">context</param>
/// <param name="data">file</param>
/// <param name="length">length of file</param>
/// <returns></returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_loadines(IntPtr e, byte[] data, int length);
/// <summary>
/// set audio sample rate
/// </summary>
/// <param name="e">context</param>
/// <param name="rate">hz</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_set_sample_rate(IntPtr e, int rate);
/// <summary>
/// get required min dimensions of output video buffer (8bpp)
/// </summary>
/// <param name="e">context</param>
/// <param name="width">width</param>
/// <param name="height">height</param>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern void qn_get_image_dimensions(IntPtr e, ref int width, ref int height);
/// <summary>
/// set output video buffer that will be used for all subsequent renders until replaced
/// </summary>
/// <param name="e">context</param>
/// <param name="dest">8bpp, at least as big as qn_get_image_dimensions()</param>
/// <param name="pitch">byte pitch</param>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern void qn_set_pixels(IntPtr e, byte[] dest, int pitch);
/// <summary>
/// emulate a single frame
/// </summary>
/// <param name="e">context</param>
/// <param name="pad1">pad 1 input</param>
/// <param name="pad2">pad 2 input</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_emulate_frame(IntPtr e, int pad1, int pad2);
/// <summary>
/// get number of times joypad was read in most recent frame
/// </summary>
/// <param name="e">context</param>
/// <returns>0 means lag</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern int qn_get_joypad_read_count(IntPtr e);
/// <summary>
/// get audio info for most recent frame
/// </summary>
/// <param name="e">context</param>
/// <param name="sample_count">number of samples actually created</param>
/// <param name="chan_count">1 for mono, 2 for stereo</param>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern void qn_get_audio_info(IntPtr e, ref int sample_count, ref int chan_count);
/// <summary>
/// get audio for most recent frame. must not be called more than once per frame!
/// </summary>
/// <param name="e">context</param>
/// <param name="dest">sample buffer</param>
/// <param name="max_samples">length to read into sample buffer</param>
/// <returns>length actually read</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern int qn_read_audio(IntPtr e, short[] dest, int max_samples);
/// <summary>
/// reset the console
/// </summary>
/// <param name="e">context</param>
/// <param name="hard">true for powercycle, false for reset button</param>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern void qn_reset(IntPtr e, bool hard);
/// <summary>
/// get the required byte size of a savestate
/// </summary>
/// <param name="e">context</param>
/// <param name="size">size is returned</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_state_size(IntPtr e, ref int size);
/// <summary>
/// save state to buffer
/// </summary>
/// <param name="e">context</param>
/// <param name="dest">buffer</param>
/// <param name="size">length of buffer</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_state_save(IntPtr e, byte[] dest, int size);
/// <summary>
/// load state from buffer
/// </summary>
/// <param name="e">context</param>
/// <param name="src">buffer</param>
/// <param name="size">length of buffer</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_state_load(IntPtr e, byte[] src, int size);
/// <summary>
/// query battery ram state
/// </summary>
/// <param name="e">context</param>
/// <returns>true if battery backup sram exists</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern bool qn_has_battery_ram(IntPtr e);
/// <summary>
/// query battery ram size
/// </summary>
/// <param name="e">context</param>
/// <param name="size">size is returned</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_battery_ram_size(IntPtr e, ref int size);
/// <summary>
/// save battery ram to buffer
/// </summary>
/// <param name="e">context</param>
/// <param name="dest">buffer</param>
/// <param name="size">size</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_battery_ram_save(IntPtr e, byte[] dest, int size);
/// <summary>
/// load battery ram from buffer
/// </summary>
/// <param name="e">context</param>
/// <param name="src">buffer</param>
/// <param name="size">size</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_battery_ram_load(IntPtr e, byte[] src, int size);
/// <summary>
/// clear battery ram
/// </summary>
/// <param name="e">context</param>
/// <returns>string error</returns>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_battery_ram_clear(IntPtr e);
/// <summary>
/// set sprite limit; does not affect emulation
/// </summary>
/// <param name="e">context</param>
/// <param name="n">0 to hide, 8 for normal, 64 for all</param>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern void qn_set_sprite_limit(IntPtr e, int n);
/// <summary>
/// handle "string error" as returned by some quicknes functions
/// </summary>
/// <param name="p"></param>
public static void ThrowStringError(IntPtr p)
{
if (p == IntPtr.Zero)
return;
string s = Marshal.PtrToStringAnsi(p);
throw new InvalidOperationException("LibQuickNES error: " + s);
}
}
}

162
quicknes/bizinterface.cpp Normal file
View File

@ -0,0 +1,162 @@
#include <cstdlib>
#include <cstring>
#include "nes_emu/Nes_Emu.h"
// simulate the write so we'll know how long the buffer needs to be
class Sim_Writer : public Data_Writer
{
long size_;
public:
Sim_Writer():size_(0) { }
error_t write(const void *, long size)
{
size_ += size;
return 0;
}
long size() const { return size_; }
};
#define EXPORT extern "C" __declspec(dllexport)
EXPORT Nes_Emu *qn_new()
{
return new Nes_Emu();
}
EXPORT void qn_delete(Nes_Emu *e)
{
delete e;
}
EXPORT const char *qn_loadines(Nes_Emu *e, const void *data, int length)
{
Mem_File_Reader r = Mem_File_Reader(data, length);
Auto_File_Reader a = Auto_File_Reader(r);
return e->load_ines(a);
}
EXPORT const char *qn_set_sample_rate(Nes_Emu *e, int rate)
{
return e->set_sample_rate(rate);
}
EXPORT void qn_get_image_dimensions(Nes_Emu *e, int *width, int *height)
{
if (width)
*width = e->buffer_width;
if (height)
*height = e->buffer_height();
}
EXPORT void qn_set_pixels(Nes_Emu *e, void *dest, int pitch)
{
e->set_pixels(dest, pitch);
}
EXPORT const char *qn_emulate_frame(Nes_Emu *e, int pad1, int pad2)
{
return e->emulate_frame(pad1, pad2);
}
EXPORT int qn_get_joypad_read_count(Nes_Emu *e)
{
return e->frame().joypad_read_count;
}
EXPORT void qn_get_audio_info(Nes_Emu *e, int *sample_count, int *chan_count)
{
if (sample_count)
*sample_count = e->frame().sample_count;
if (chan_count)
*chan_count = e->frame().chan_count;
}
EXPORT int qn_read_audio(Nes_Emu *e, short *dest, int max_samples)
{
return e->read_samples(dest, max_samples);
}
EXPORT void qn_reset(Nes_Emu *e, int hard)
{
e->reset(hard);
}
EXPORT const char *qn_state_size(Nes_Emu *e, int *size)
{
Sim_Writer w = Sim_Writer();
Auto_File_Writer a = Auto_File_Writer(w);
const char *ret = e->save_state(a);
if (size)
*size = w.size();
return ret;
}
EXPORT const char *qn_state_save(Nes_Emu *e, void *dest, int size)
{
Mem_Writer w = Mem_Writer(dest, size, 0);
Auto_File_Writer a = Auto_File_Writer(w);
const char *ret = e->save_state(a);
if (!ret && w.size() != size)
return "Buffer Underrun!";
return ret;
}
EXPORT const char *qn_state_load(Nes_Emu *e, const void *src, int size)
{
Mem_File_Reader r = Mem_File_Reader(src, size);
Auto_File_Reader a = Auto_File_Reader(r);
return e->load_state(a);
}
EXPORT int qn_has_battery_ram(Nes_Emu *e)
{
return e->has_battery_ram();
}
EXPORT const char *qn_battery_ram_size(Nes_Emu *e, int *size)
{
Sim_Writer w = Sim_Writer();
Auto_File_Writer a = Auto_File_Writer(w);
const char *ret = e->save_battery_ram(a);
if (size)
*size = w.size();
return ret;
}
EXPORT const char *qn_battery_ram_save(Nes_Emu *e, void *dest, int size)
{
Mem_Writer w = Mem_Writer(dest, size, 0);
Auto_File_Writer a = Auto_File_Writer(w);
const char *ret = e->save_battery_ram(a);
if (!ret && w.size() != size)
return "Buffer Underrun!";
return ret;
}
EXPORT const char *qn_battery_ram_load(Nes_Emu *e, const void *src, int size)
{
Mem_File_Reader r = Mem_File_Reader(src, size);
Auto_File_Reader a = Auto_File_Reader(r);
return e->load_battery_ram(a);
}
EXPORT const char *qn_battery_ram_clear(Nes_Emu *e)
{
int size = 0;
const char *ret = qn_battery_ram_size(e, &size);
if (ret)
return ret;
void *data = std::malloc(size);
if (!data)
return "Out of Memory!";
std::memset(data, 0xff, size);
ret = qn_battery_ram_load(e, data, size);
std::free(data);
return ret;
}
EXPORT void qn_set_sprite_limit(Nes_Emu *e, int n)
{
e->set_sprite_mode((Nes_Emu::sprite_mode_t)n);
}

View File

@ -11,6 +11,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\bizinterface.cpp" />
<ClCompile Include="..\fex\blargg_common.cpp" />
<ClCompile Include="..\fex\blargg_errors.cpp" />
<ClCompile Include="..\fex\Data_Reader.cpp" />
@ -85,7 +86,7 @@
<Optimization>Disabled</Optimization>
<DisableSpecificWarnings>4244;4800;4804;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(ProjectDir)\..</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);DLLEXPORT=__declspec(dllexport)</PreprocessorDefinitions>
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);DISABLE_AUTO_FILE</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -102,7 +103,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<DisableSpecificWarnings>4244;4800;4804;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(ProjectDir)\..</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);DLLEXPORT=__declspec(dllexport)</PreprocessorDefinitions>
<PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);DISABLE_AUTO_FILE</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>

View File

@ -144,5 +144,8 @@
<ClCompile Include="..\fex\Data_Reader.cpp">
<Filter>Source Files\fex</Filter>
</ClCompile>
<ClCompile Include="..\bizinterface.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>