Beispiel #1
0
        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");
            }
        }
Beispiel #3
0
        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");
            }
        }
Beispiel #4
0
        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");
            }
        }
Beispiel #5
0
        /*
         * 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();
            }
        }
Beispiel #6
0
        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 }");
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }