private void MAMESoundCallback() { int bytesPerSample = 2; IntPtr ptr = LibMAME.mame_lua_get_string(MAMELuaCommand.GetSamples, out var lengthInBytes); if (ptr == IntPtr.Zero) { Console.WriteLine("LibMAME ERROR: audio buffer pointer is null"); return; } _numSamples = lengthInBytes / bytesPerSample; unsafe { short *pSample = (short *)ptr.ToPointer(); for (int i = 0; i < _numSamples; i++) { _audioSamples.Enqueue(*(pSample + i)); _dAudioSamples++; } } if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: audio buffer wasn't freed"); } }
private void UpdateVideo() { BufferWidth = LibMAME.mame_lua_get_int(MAMELuaCommand.GetWidth); BufferHeight = LibMAME.mame_lua_get_int(MAMELuaCommand.GetHeight); int expectedSize = BufferWidth * BufferHeight; int bytesPerPixel = 4; IntPtr ptr = LibMAME.mame_lua_get_string(MAMELuaCommand.GetPixels, out var lengthInBytes); if (ptr == IntPtr.Zero) { Console.WriteLine("LibMAME ERROR: frame buffer pointer is null"); return; } if (expectedSize * bytesPerPixel != lengthInBytes) { Console.WriteLine( "LibMAME ERROR: frame buffer has wrong size\n" + $"width: { BufferWidth } pixels\n" + $"height: { BufferHeight } pixels\n" + $"expected: { expectedSize * bytesPerPixel } bytes\n" + $"received: { lengthInBytes } bytes\n"); return; } _frameBuffer = new int[expectedSize]; Marshal.Copy(ptr, _frameBuffer, 0, expectedSize); if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: frame buffer wasn't freed"); } }
private void GetInputFields() { int lengthInBytes; IntPtr ptr = LibMAME.mame_lua_get_string(MAMELuaCommand.GetInputFields, out lengthInBytes); if (ptr == IntPtr.Zero) { Console.WriteLine("LibMAME ERROR: string buffer pointer is null"); return; } string inputFields = Marshal.PtrToStringAnsi(ptr, lengthInBytes); string[] portFields = inputFields.Split(';'); MAMEController.BoolButtons.Clear(); foreach (string portField in portFields) { if (portField != string.Empty) { string[] substrings = portField.Split(','); string tag = substrings.First(); string field = substrings.Last(); fieldsPorts.Add(field, tag); MAMEController.BoolButtons.Add(field); } } if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: string buffer wasn't freed"); } }
private void UpdateGameName() { int lengthInBytes; IntPtr ptr = LibMAME.mame_lua_get_string(MAMELuaCommand.GetGameName, out lengthInBytes); gameName = Marshal.PtrToStringAnsi(ptr, lengthInBytes); if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: string buffer wasn't freed"); } }
/* * FrameAdvance() and MAME * * MAME fires the periodic callback on every video and debugger update, * which happens every VBlank and also repeatedly at certain time * intervals while paused. Since MAME's luaengine runs in a separate * thread, it's only safe to update everything we need per frame during * this callback, when it's explicitly waiting for further lua commands. * * If we disable throttling and pass -update_in_pause, there will be no * delay between video updates. This allows to run at full speed while * frame-stepping. * * MAME only captures new frame data once per VBlank, while unpaused. * But it doesn't have an exclusive VBlank callback we could attach to. * It has a LUA_ON_FRAME_DONE callback, but that fires even more * frequently and updates all sorts of other non-video stuff, and we * need none of that here. * * So we filter out all the calls that happen while paused (non-VBlank * updates). Then, when Hawk asks us to advance a frame, we virtually * unpause and declare the new frame unfinished. This informs MAME that * it should advance one frame internally. Hawk starts waiting for the * MAME thread to complete the request. * * After MAME's done advancing, it fires the periodic callback again. * That's when we update everything and declare the new frame finished, * filtering out any further updates again. Then we allow Hawk to * complete frame-advancing. */ private void MAMEPeriodicCallback() { if (_exiting) { LibMAME.mame_lua_execute(MAMELuaCommand.Exit); _exiting = false; } if (_memAccess) { _mamePeriodicComplete.Set(); _memoryAccessComplete.WaitOne(); return; } //int MAMEFrame = LibMAME.mame_lua_get_int(MAMELuaCommand.GetFrameNumber); if (!_paused) { LibMAME.mame_lua_execute(MAMELuaCommand.Step); _frameDone = false; _paused = true; } else if (!_frameDone) { IntPtr ptr = LibMAME.mame_lua_get_string(MAMELuaCommand.GetSpaceBuffer, out var lengthInBytes); if (ptr == IntPtr.Zero) { Console.WriteLine("LibMAME ERROR: audio buffer pointer is null"); return; } //byte[] buf = new byte[lengthInBytes]; //Marshal.Copy(ptr, buf, 0, lengthInBytes); if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: audio buffer wasn't freed"); } Update(); _frameDone = true; _mameFrameComplete.Set(); } }
private void CheckVersions() { int lengthInBytes; IntPtr ptr = LibMAME.mame_lua_get_string(MAMELuaCommand.GetVersion, out lengthInBytes); string MAMEVersion = Marshal.PtrToStringAnsi(ptr, lengthInBytes); if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: string buffer wasn't freed"); } string version = this.Attributes().PortedVersion; Debug.Assert(version == MAMEVersion, "MAME versions desync!\n\n" + $"MAME is { MAMEVersion }\n" + $"MAMEHawk is { version }"); }
private static string MameGetString(string command) { IntPtr ptr = LibMAME.mame_lua_get_string(command, out var lengthInBytes); if (ptr == IntPtr.Zero) { Console.WriteLine("LibMAME ERROR: string buffer pointer is null"); return(""); } var ret = Marshal.PtrToStringAnsi(ptr, lengthInBytes); if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: string buffer wasn't freed"); } return(ret); }
public void SaveStateBinary(BinaryWriter writer) { IntPtr ptr = LibMAME.mame_lua_get_string("return manager:machine():buffer_save()", out var lengthInBytes); if (ptr == IntPtr.Zero) { Console.WriteLine("LibMAME ERROR: audio buffer pointer is null"); return; } Marshal.Copy(ptr, _mameSaveBuffer, 0, lengthInBytes); if (!LibMAME.mame_lua_free_string(ptr)) { Console.WriteLine("LibMAME ERROR: audio buffer wasn't freed"); } writer.Write(_mameSaveBuffer.Length); writer.Write(_mameSaveBuffer); writer.Write(Frame); }