CAPCOM YM2151 主要高频函数 unsafe 指针优化 | CPS NeoGeo PGS draw 函数 指针优化
This commit is contained in:
parent
0fc5acac4c
commit
0634207bf0
@ -20,6 +20,14 @@ namespace MAME.Core
|
|||||||
{
|
{
|
||||||
Act_Log?.Invoke(msg);
|
Act_Log?.Invoke(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void Assert(bool conditional, string msg)
|
||||||
|
{
|
||||||
|
if (conditional)
|
||||||
|
return;
|
||||||
|
Act_Log?.Invoke(msg);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
417
MAME.Unity/Assets/Plugins/UMAME/ObjectPoolAuto.cs
Normal file
417
MAME.Unity/Assets/Plugins/UMAME/ObjectPoolAuto.cs
Normal file
@ -0,0 +1,417 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace MAME.Core
|
||||||
|
{
|
||||||
|
internal static class ObjectPoolAuto
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或者创建一个新的
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
|
||||||
|
public static T Acquire<T>()
|
||||||
|
where T : class, new()
|
||||||
|
=> ObjectPool<T>.Acquire();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或者创建一个新的
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
|
||||||
|
public static void Acquire<T>(out T item)
|
||||||
|
where T : class, new()
|
||||||
|
=> item = ObjectPool<T>.Acquire();
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(T item)
|
||||||
|
where T : class, new()
|
||||||
|
=> ObjectPool<T>.Release(item);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(ref T item) where T : class, new()
|
||||||
|
{
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
ObjectPool<T>.Release(item);
|
||||||
|
item = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
public const string
|
||||||
|
NotClearError = " They must be cleared before being released to the pool and not modified after that.";
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或创建List
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release{T}(List{T})"/> 回收参见此方法</remarks>
|
||||||
|
public static List<T> AcquireList<T>()
|
||||||
|
{
|
||||||
|
var list = ObjectPool<List<T>>.Acquire();
|
||||||
|
EmuLogger.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收List
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(List<T> list)
|
||||||
|
{
|
||||||
|
list.Clear();
|
||||||
|
ObjectPool<List<T>>.Release(list);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 回收List内容
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="list"></param>
|
||||||
|
public static void ReleaseListContent<T>(List<T> list) where T : class, new()
|
||||||
|
{
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
ObjectPool<T>.Release(item);
|
||||||
|
}
|
||||||
|
list.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或创建HashSet
|
||||||
|
/// </summary>
|
||||||
|
public static HashSet<T> AcquireSet<T>()
|
||||||
|
{
|
||||||
|
var set = ObjectPool<HashSet<T>>.Acquire();
|
||||||
|
EmuLogger.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放HashSet
|
||||||
|
/// </summary>
|
||||||
|
public static void Release<T>(HashSet<T> set)
|
||||||
|
{
|
||||||
|
set.Clear();
|
||||||
|
ObjectPool<HashSet<T>>.Release(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个字符串StringBuilder
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release(StringBuilder)"/>回收参见这个</remarks>
|
||||||
|
public static StringBuilder AcquireStringBuilder()
|
||||||
|
{
|
||||||
|
var builder = ObjectPool<StringBuilder>.Acquire();
|
||||||
|
EmuLogger.Assert(builder.Length == 0, $"A pooled {nameof(StringBuilder)} is not empty." + NotClearError);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收 StringBuilder
|
||||||
|
/// </summary>
|
||||||
|
public static void Release(StringBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Length = 0;
|
||||||
|
ObjectPool<StringBuilder>.Release(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收 StringBuilder
|
||||||
|
/// </summary>
|
||||||
|
public static string ReleaseToString(this StringBuilder builder)
|
||||||
|
{
|
||||||
|
var result = builder.ToString();
|
||||||
|
Release(builder);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private static class Cache<T>
|
||||||
|
{
|
||||||
|
public static readonly Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>
|
||||||
|
Results = new Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 此方法主要用于频繁绘制缓存,比如说GUI绘制
|
||||||
|
/// </summary>
|
||||||
|
public static T GetCachedResult<T>(Func<T> function)
|
||||||
|
{
|
||||||
|
var method = function.Method;
|
||||||
|
if (!Cache<T>.Results.TryGetValue(method, out var result))
|
||||||
|
{
|
||||||
|
|
||||||
|
result = new KeyValuePair<Func<T>, T>(function, function());
|
||||||
|
Cache<T>.Results.Add(method, result);
|
||||||
|
}
|
||||||
|
else if (result.Key != function)
|
||||||
|
{
|
||||||
|
EmuLogger.Log(
|
||||||
|
$"{nameof(GetCachedResult)}<{typeof(T).Name}>" +
|
||||||
|
$" was previously called on {method.Name} with a different target." +
|
||||||
|
" This likely means that a new delegate is being passed into every call" +
|
||||||
|
" so it can't actually return the same cached object.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
public static class Disposable
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable Acquire<T>(out T item)
|
||||||
|
where T : class, new()
|
||||||
|
=> ObjectPool<T>.Disposable.Acquire(out item);
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable AcquireList<T>(out List<T> list)
|
||||||
|
{
|
||||||
|
var disposable = ObjectPool<List<T>>.Disposable.Acquire(out list, onRelease: (l) => l.Clear());
|
||||||
|
EmuLogger.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
|
||||||
|
return disposable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="HashSet{T}"/> if
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable AcquireSet<T>(out HashSet<T> set)
|
||||||
|
{
|
||||||
|
var disposable = ObjectPool<HashSet<T>>.Disposable.Acquire(out set, onRelease: (s) => s.Clear());
|
||||||
|
EmuLogger.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
|
||||||
|
return disposable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
}
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
public static class ObjectPool<T> where T : class, new()
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private static readonly List<T>
|
||||||
|
Items = new List<T>();
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>The number of spare items currently in the pool.</summary>
|
||||||
|
public static int Count
|
||||||
|
{
|
||||||
|
get => Items.Count;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
var count = Items.Count;
|
||||||
|
if (count < value)
|
||||||
|
{
|
||||||
|
if (Items.Capacity < value)
|
||||||
|
Items.Capacity = Mathf.NextPowerOfTwo(value);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Items.Add(new T());
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
while (count < value);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (count > value)
|
||||||
|
{
|
||||||
|
Items.RemoveRange(value, count - value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the <see cref="Count"/> is less than the specified value, this method increases it to that value by
|
||||||
|
/// creating new objects.
|
||||||
|
/// </summary>
|
||||||
|
public static void SetMinCount(int count)
|
||||||
|
{
|
||||||
|
if (Count < count)
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>The <see cref="List{T}.Capacity"/> of the internal list of spare items.</summary>
|
||||||
|
public static int Capacity
|
||||||
|
{
|
||||||
|
get => Items.Capacity;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Items.Count > value)
|
||||||
|
Items.RemoveRange(value, Items.Count - value);
|
||||||
|
Items.Capacity = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>Returns a spare item if there are any, or creates a new one.</summary>
|
||||||
|
/// <remarks>Remember to <see cref="Release(T)"/> it when you are done.</remarks>
|
||||||
|
public static T Acquire()
|
||||||
|
{
|
||||||
|
var count = Items.Count;
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count--;
|
||||||
|
var item = Items[count];
|
||||||
|
Items.RemoveAt(count);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>Adds the `item` to the list of spares so it can be reused.</summary>
|
||||||
|
public static void Release(T item)
|
||||||
|
{
|
||||||
|
Items.Add(item);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>Returns a description of the state of this pool.</summary>
|
||||||
|
public static string GetDetails()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
$"{typeof(T).Name}" +
|
||||||
|
$" ({nameof(Count)} = {Items.Count}" +
|
||||||
|
$", {nameof(Capacity)} = {Items.Capacity}" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="IDisposable"/> system to allow pooled objects to be acquired and released within <c>using</c>
|
||||||
|
/// statements instead of needing to manually release everything.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class Disposable : IDisposable
|
||||||
|
{
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private static readonly List<Disposable> LazyStack = new List<Disposable>();
|
||||||
|
|
||||||
|
private static int _ActiveDisposables;
|
||||||
|
|
||||||
|
private T _Item;
|
||||||
|
private Action<T> _OnRelease;
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
private Disposable() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls <see cref="ObjectPool{T}.Acquire"/> to set the `item` and returns an <see cref="IDisposable"/>
|
||||||
|
/// that will call <see cref="Release(T)"/> on the `item` when disposed.
|
||||||
|
/// </summary>
|
||||||
|
public static IDisposable Acquire(out T item, Action<T> onRelease = null)
|
||||||
|
{
|
||||||
|
Disposable disposable;
|
||||||
|
|
||||||
|
if (LazyStack.Count <= _ActiveDisposables)
|
||||||
|
{
|
||||||
|
LazyStack.Add(disposable = new Disposable());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
disposable = LazyStack[_ActiveDisposables];
|
||||||
|
}
|
||||||
|
|
||||||
|
_ActiveDisposables++;
|
||||||
|
|
||||||
|
disposable._Item = item = ObjectPool<T>.Acquire();
|
||||||
|
disposable._OnRelease = onRelease;
|
||||||
|
return disposable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
_OnRelease?.Invoke(_Item);
|
||||||
|
Release(_Item);
|
||||||
|
_ActiveDisposables--;
|
||||||
|
}
|
||||||
|
/************************************************************************************************************************/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ExtFunctions
|
||||||
|
public struct PoolHandle<T> : IDisposable
|
||||||
|
where T : class, new()
|
||||||
|
{
|
||||||
|
public T Ins;
|
||||||
|
internal static PoolHandle<T> Create(T poolIns)
|
||||||
|
{
|
||||||
|
return new PoolHandle<T> { Ins = poolIns };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ObjectPoolAuto.Release<T>(Ins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct PoolListHandle<T> : IDisposable
|
||||||
|
{
|
||||||
|
public List<T> Ins;
|
||||||
|
internal static PoolListHandle<T> Create(List<T> poolIns)
|
||||||
|
{
|
||||||
|
return new PoolListHandle<T> { Ins = poolIns };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ObjectPoolAuto.Release<T>(Ins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PoolHandle<T> PoolScope<T>()
|
||||||
|
where T : class, new()
|
||||||
|
{
|
||||||
|
return PoolHandle<T>.Create(ObjectPoolAuto.Acquire<T>());
|
||||||
|
}
|
||||||
|
public static PoolListHandle<T> PoolListScope<T>()
|
||||||
|
{
|
||||||
|
return PoolListHandle<T>.Create(ObjectPoolAuto.AcquireList<T>());
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
11
MAME.Unity/Assets/Plugins/UMAME/ObjectPoolAuto.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/ObjectPoolAuto.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f22c2fa157c9e6045ad5307124c8a365
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -61,7 +61,10 @@ namespace cpu.nec
|
|||||||
{
|
{
|
||||||
if (line >= 0 && line < 35)
|
if (line >= 0 && line < 35)
|
||||||
{
|
{
|
||||||
Cpuint.lirq.Add(new irq(cpunum, line, state, vector, EmuTimer.get_current_time()));
|
irq _irq = ObjectPoolAuto.Acquire<irq>();
|
||||||
|
_irq.Init(cpunum, line, state, vector, EmuTimer.get_current_time());
|
||||||
|
Cpuint.lirq.Add(_irq);
|
||||||
|
//Cpuint.lirq.Add(new irq(cpunum, line, state, vector, EmuTimer.get_current_time()));
|
||||||
int event_index = Cpuint.input_event_index[cpunum, line]++;
|
int event_index = Cpuint.input_event_index[cpunum, line]++;
|
||||||
if (event_index >= 35)
|
if (event_index >= 35)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace MAME.Core
|
namespace MAME.Core
|
||||||
@ -57,7 +58,7 @@ namespace MAME.Core
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
public irq(int _cpunum, int _line, LineState _state, int _vector, Atime _time)
|
public void Init(int _cpunum, int _line, LineState _state, int _vector, Atime _time)
|
||||||
{
|
{
|
||||||
cpunum = _cpunum;
|
cpunum = _cpunum;
|
||||||
line = _line;
|
line = _line;
|
||||||
@ -134,7 +135,10 @@ namespace MAME.Core
|
|||||||
public static void cpunum_set_input_line(int cpunum, int line, LineState state)
|
public static void cpunum_set_input_line(int cpunum, int line, LineState state)
|
||||||
{
|
{
|
||||||
int vector = (line >= 0 && line < 35) ? interrupt_vector[cpunum, line] : 0xff;
|
int vector = (line >= 0 && line < 35) ? interrupt_vector[cpunum, line] : 0xff;
|
||||||
lirq.Add(new irq(cpunum, line, state, vector, EmuTimer.get_current_time()));
|
irq _irq = ObjectPoolAuto.Acquire<irq>();
|
||||||
|
_irq.Init(cpunum, line, state, vector, EmuTimer.get_current_time());
|
||||||
|
lirq.Add(_irq);
|
||||||
|
//lirq.Add(new irq(cpunum, line, state, vector, EmuTimer.get_current_time()));
|
||||||
Cpuexec.cpu[cpunum].cpunum_set_input_line_and_vector(cpunum, line, state, vector);
|
Cpuexec.cpu[cpunum].cpunum_set_input_line_and_vector(cpunum, line, state, vector);
|
||||||
}
|
}
|
||||||
public static void cpunum_set_input_line_vector(int cpunum, int line, int vector)
|
public static void cpunum_set_input_line_vector(int cpunum, int line, int vector)
|
||||||
@ -149,13 +153,17 @@ namespace MAME.Core
|
|||||||
{
|
{
|
||||||
if (line >= 0 && line < 35)
|
if (line >= 0 && line < 35)
|
||||||
{
|
{
|
||||||
lirq.Add(new irq(cpunum, line, state, vector, EmuTimer.get_current_time()));
|
irq _irq = ObjectPoolAuto.Acquire<irq>();
|
||||||
|
_irq.Init(cpunum, line, state, vector, EmuTimer.get_current_time());
|
||||||
|
lirq.Add(_irq);
|
||||||
|
//lirq.Add(new irq(cpunum, line, state, vector, EmuTimer.get_current_time()));
|
||||||
EmuTimer.timer_set_internal(EmuTimer.TIME_ACT.Cpuint_cpunum_empty_event_queue);
|
EmuTimer.timer_set_internal(EmuTimer.TIME_ACT.Cpuint_cpunum_empty_event_queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void cpunum_empty_event_queue()
|
public static void cpunum_empty_event_queue()
|
||||||
{
|
{
|
||||||
List<irq> lsirq = new List<irq>();
|
//List<irq> lsirq = new List<irq>();
|
||||||
|
List<irq> lsirq = ObjectPoolAuto.AcquireList<irq>();
|
||||||
if (lirq.Count == 0)
|
if (lirq.Count == 0)
|
||||||
{
|
{
|
||||||
int i1 = 1;
|
int i1 = 1;
|
||||||
@ -219,12 +227,14 @@ namespace MAME.Core
|
|||||||
foreach (irq irq1 in lsirq)
|
foreach (irq irq1 in lsirq)
|
||||||
{
|
{
|
||||||
input_event_index[irq1.cpunum, irq1.line] = 0;
|
input_event_index[irq1.cpunum, irq1.line] = 0;
|
||||||
|
ObjectPoolAuto.Release(irq1);
|
||||||
lirq.Remove(irq1);
|
lirq.Remove(irq1);
|
||||||
}
|
}
|
||||||
if (lirq.Count > 0)
|
if (lirq.Count > 0)
|
||||||
{
|
{
|
||||||
int i1 = 1;
|
int i1 = 1;
|
||||||
}
|
}
|
||||||
|
ObjectPoolAuto.Release(lsirq);
|
||||||
}
|
}
|
||||||
public static int cpu_irq_callback(int cpunum, int line)
|
public static int cpu_irq_callback(int cpunum, int line)
|
||||||
{
|
{
|
||||||
@ -348,7 +358,9 @@ namespace MAME.Core
|
|||||||
lirq = new List<irq>();
|
lirq = new List<irq>();
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
lirq.Add(new irq());
|
irq _irq = ObjectPoolAuto.Acquire<irq>();
|
||||||
|
lirq.Add(_irq);
|
||||||
|
//lirq.Add(new irq());
|
||||||
lirq[i].cpunum = reader.ReadInt32();
|
lirq[i].cpunum = reader.ReadInt32();
|
||||||
lirq[i].line = reader.ReadInt32();
|
lirq[i].line = reader.ReadInt32();
|
||||||
lirq[i].state = (LineState)reader.ReadInt32();
|
lirq[i].state = (LineState)reader.ReadInt32();
|
||||||
|
@ -25,10 +25,6 @@ namespace MAME.Core
|
|||||||
public Atime period;
|
public Atime period;
|
||||||
public Atime start;
|
public Atime start;
|
||||||
public Atime expire;
|
public Atime expire;
|
||||||
public emu_timer()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public class emu_timer2
|
public class emu_timer2
|
||||||
{
|
{
|
||||||
@ -502,16 +498,18 @@ namespace MAME.Core
|
|||||||
lt.Insert(i, timer1);
|
lt.Insert(i, timer1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<emu_timer> timer_list_remove_lt1 = new List<emu_timer>();
|
||||||
public static void timer_list_remove(emu_timer timer1)
|
public static void timer_list_remove(emu_timer timer1)
|
||||||
{
|
{
|
||||||
if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector)
|
if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector)
|
||||||
{
|
{
|
||||||
List<emu_timer> lt1 = new List<emu_timer>();
|
timer_list_remove_lt1.Clear();
|
||||||
foreach (emu_timer et in lt)
|
foreach (emu_timer et in lt)
|
||||||
{
|
{
|
||||||
if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) == 0)
|
if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) == 0)
|
||||||
{
|
{
|
||||||
lt1.Add(et);
|
timer_list_remove_lt1.Add(et);
|
||||||
//lt.Remove(et);
|
//lt.Remove(et);
|
||||||
//break;
|
//break;
|
||||||
}
|
}
|
||||||
@ -524,7 +522,7 @@ namespace MAME.Core
|
|||||||
int i1 = 1;
|
int i1 = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (emu_timer et1 in lt1)
|
foreach (emu_timer et1 in timer_list_remove_lt1)
|
||||||
{
|
{
|
||||||
lt.Remove(et1);
|
lt.Remove(et1);
|
||||||
}
|
}
|
||||||
|
@ -145,165 +145,533 @@ namespace MAME.Core
|
|||||||
return (((max_y >= y) && (scanline >= y) && (scanline <= max_y)) ||
|
return (((max_y >= y) && (scanline >= y) && (scanline <= max_y)) ||
|
||||||
((max_y < y) && ((scanline >= y) || (scanline <= max_y))));
|
((max_y < y) && ((scanline >= y) || (scanline <= max_y))));
|
||||||
}
|
}
|
||||||
private static void draw_sprites(int iBitmap, int scanline)
|
|
||||||
|
//private static void draw_sprites(int iBitmap, int scanline)
|
||||||
|
//{
|
||||||
|
// int x_2, code_2;
|
||||||
|
// int x, y, rows, zoom_x, zoom_y, sprite_list_offset, sprite_index, max_sprite_index, sprite_number, sprite_y, tile, attr_and_code_offs, code, zoom_x_table_offset, gfx_offset, line_pens_offset, x_inc, sprite_line, zoom_line;
|
||||||
|
// ushort y_control, zoom_control, attr;
|
||||||
|
// byte sprite_y_and_tile;
|
||||||
|
// bool invert;
|
||||||
|
// y = 0;
|
||||||
|
// x = 0;
|
||||||
|
// rows = 0;
|
||||||
|
// zoom_y = 0;
|
||||||
|
// zoom_x = 0;
|
||||||
|
// if ((scanline & 0x01) != 0)
|
||||||
|
// {
|
||||||
|
// sprite_list_offset = 0x8680;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// sprite_list_offset = 0x8600;
|
||||||
|
// }
|
||||||
|
// Span<ushort> span_neogeo_videoram = neogeo_videoram.AsSpan();
|
||||||
|
// Span<int> span_bitmapbaseN_iBitmap = Video.bitmapbaseN[iBitmap].AsSpan();
|
||||||
|
// Span<byte> span_sprite_gfx = sprite_gfx.AsSpan();
|
||||||
|
// Span<int> span_pens = pens.AsSpan();
|
||||||
|
// for (max_sprite_index = 95; max_sprite_index >= 0; max_sprite_index--)
|
||||||
|
// {
|
||||||
|
// if (span_neogeo_videoram[sprite_list_offset + max_sprite_index] != 0)
|
||||||
|
// {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (max_sprite_index != 95)
|
||||||
|
// {
|
||||||
|
// max_sprite_index = max_sprite_index + 1;
|
||||||
|
// }
|
||||||
|
// for (sprite_index = 0; sprite_index < max_sprite_index; sprite_index++)
|
||||||
|
// {
|
||||||
|
// sprite_number = span_neogeo_videoram[sprite_list_offset + sprite_index] & 0x1ff;
|
||||||
|
// y_control = span_neogeo_videoram[0x8200 | sprite_number];
|
||||||
|
// zoom_control = span_neogeo_videoram[0x8000 | sprite_number];
|
||||||
|
// x_2 = span_neogeo_videoram[0x8400 | sprite_number];
|
||||||
|
// code_2 = span_neogeo_videoram[sprite_number << 6];
|
||||||
|
// if ((y_control & 0x40) != 0)
|
||||||
|
// {
|
||||||
|
// x = (x + zoom_x + 1) & 0x01ff;
|
||||||
|
// zoom_x = (zoom_control >> 8) & 0x0f;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// y = 0x200 - (y_control >> 7);
|
||||||
|
// x = span_neogeo_videoram[0x8400 | sprite_number] >> 7;
|
||||||
|
// zoom_y = zoom_control & 0xff;
|
||||||
|
// zoom_x = (zoom_control >> 8) & 0x0f;
|
||||||
|
// rows = y_control & 0x3f;
|
||||||
|
// }
|
||||||
|
// if ((x >= 0x140) && (x <= 0x1f0))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (sprite_on_scanline(scanline, y, rows))
|
||||||
|
// {
|
||||||
|
// sprite_line = (scanline - y) & 0x1ff;
|
||||||
|
// zoom_line = sprite_line & 0xff;
|
||||||
|
// invert = ((sprite_line & 0x100) != 0) ? true : false;
|
||||||
|
// if (invert)
|
||||||
|
// {
|
||||||
|
// zoom_line ^= 0xff;
|
||||||
|
// }
|
||||||
|
// if (rows > 0x20)
|
||||||
|
// {
|
||||||
|
// zoom_line = zoom_line % ((zoom_y + 1) << 1);
|
||||||
|
// if (zoom_line > zoom_y)
|
||||||
|
// {
|
||||||
|
// zoom_line = ((zoom_y + 1) << 1) - 1 - zoom_line;
|
||||||
|
// invert = !invert;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// sprite_y_and_tile = zoomyrom[(zoom_y << 8) | zoom_line];
|
||||||
|
// sprite_y = sprite_y_and_tile & 0x0f;
|
||||||
|
// tile = sprite_y_and_tile >> 4;
|
||||||
|
// if (invert)
|
||||||
|
// {
|
||||||
|
// sprite_y ^= 0x0f;
|
||||||
|
// tile ^= 0x1f;
|
||||||
|
// }
|
||||||
|
// attr_and_code_offs = (sprite_number << 6) | (tile << 1);
|
||||||
|
// attr = span_neogeo_videoram[attr_and_code_offs + 1];
|
||||||
|
// code = ((attr << 12) & 0x70000) | span_neogeo_videoram[attr_and_code_offs];
|
||||||
|
// if (auto_animation_disabled == 0)
|
||||||
|
// {
|
||||||
|
// if ((attr & 0x0008) != 0)
|
||||||
|
// {
|
||||||
|
// code = (code & ~0x07) | (auto_animation_counter & 0x07);
|
||||||
|
// }
|
||||||
|
// else if ((attr & 0x0004) != 0)
|
||||||
|
// {
|
||||||
|
// code = (code & ~0x03) | (auto_animation_counter & 0x03);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if ((attr & 0x0002) != 0)
|
||||||
|
// {
|
||||||
|
// sprite_y ^= 0x0f;
|
||||||
|
// }
|
||||||
|
// zoom_x_table_offset = 0;
|
||||||
|
// gfx_offset = (int)(((code << 8) | (sprite_y << 4)) & sprite_gfx_address_mask);
|
||||||
|
// line_pens_offset = attr >> 8 << 4;
|
||||||
|
// if ((attr & 0x0001) != 0)
|
||||||
|
// {
|
||||||
|
// gfx_offset = gfx_offset + 0x0f;
|
||||||
|
// x_inc = -1;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// x_inc = 1;
|
||||||
|
// }
|
||||||
|
// int pixel_addr_offsetx, pixel_addr_offsety;
|
||||||
|
// if (x <= 0x01f0)
|
||||||
|
// {
|
||||||
|
// int i;
|
||||||
|
// pixel_addr_offsetx = x + NEOGEO_HBEND;
|
||||||
|
// pixel_addr_offsety = scanline;
|
||||||
|
// for (i = 0; i < 0x10; i++)
|
||||||
|
// {
|
||||||
|
// if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
||||||
|
// {
|
||||||
|
// //if (sprite_gfx[gfx_offset] != 0)
|
||||||
|
// if (span_sprite_gfx[gfx_offset] != 0)
|
||||||
|
// {
|
||||||
|
// //Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
||||||
|
// span_bitmapbaseN_iBitmap[pixel_addr_offsety * 384 + pixel_addr_offsetx] = span_pens[line_pens_offset + span_sprite_gfx[gfx_offset]];
|
||||||
|
// }
|
||||||
|
// pixel_addr_offsetx++;
|
||||||
|
// }
|
||||||
|
// zoom_x_table_offset++;
|
||||||
|
// gfx_offset += x_inc;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// int i;
|
||||||
|
// int x_save = x;
|
||||||
|
// pixel_addr_offsetx = NEOGEO_HBEND;
|
||||||
|
// pixel_addr_offsety = scanline;
|
||||||
|
// for (i = 0; i < 0x10; i++)
|
||||||
|
// {
|
||||||
|
// if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
||||||
|
// {
|
||||||
|
// if (x >= 0x200)
|
||||||
|
// {
|
||||||
|
// //if (sprite_gfx[gfx_offset] != 0)
|
||||||
|
// if (span_sprite_gfx[gfx_offset] != 0)
|
||||||
|
// {
|
||||||
|
// //Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
||||||
|
// span_bitmapbaseN_iBitmap[pixel_addr_offsety * 384 + pixel_addr_offsetx] = span_pens[line_pens_offset + span_sprite_gfx[gfx_offset]];
|
||||||
|
// }
|
||||||
|
// pixel_addr_offsetx++;
|
||||||
|
// }
|
||||||
|
// x++;
|
||||||
|
// }
|
||||||
|
// zoom_x_table_offset++;
|
||||||
|
// gfx_offset += x_inc;
|
||||||
|
// }
|
||||||
|
// x = x_save;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// draw_sprites (Unsafa 尝试提升效率)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="iBitmap"></param>
|
||||||
|
/// <param name="scanline"></param>
|
||||||
|
unsafe private static void draw_sprites(int iBitmap, int scanline)
|
||||||
{
|
{
|
||||||
int x_2, code_2;
|
|
||||||
int x, y, rows, zoom_x, zoom_y, sprite_list_offset, sprite_index, max_sprite_index, sprite_number, sprite_y, tile, attr_and_code_offs, code, zoom_x_table_offset, gfx_offset, line_pens_offset, x_inc, sprite_line, zoom_line;
|
fixed (ushort* videoramPtr = &neogeo_videoram[0])
|
||||||
ushort y_control, zoom_control, attr;
|
fixed (int* bitmapbasePtr = &Video.bitmapbaseN[iBitmap][0])
|
||||||
byte sprite_y_and_tile;
|
fixed (byte* spriteGfxPtr = &sprite_gfx[0])
|
||||||
bool invert;
|
fixed (int* pensPtr = &pens[0])
|
||||||
y = 0;
|
fixed (byte* zoomyromPtr = &zoomyrom[0])
|
||||||
x = 0;
|
|
||||||
rows = 0;
|
|
||||||
zoom_y = 0;
|
|
||||||
zoom_x = 0;
|
|
||||||
if ((scanline & 0x01) != 0)
|
|
||||||
{
|
{
|
||||||
sprite_list_offset = 0x8680;
|
ushort* neogeo_videoram = videoramPtr;
|
||||||
}
|
int* bitmapbase = bitmapbasePtr;
|
||||||
else
|
byte* spriteGfx = spriteGfxPtr;
|
||||||
{
|
int* pens = pensPtr;
|
||||||
sprite_list_offset = 0x8600;
|
byte* zoomyrom = zoomyromPtr;
|
||||||
}
|
|
||||||
for (max_sprite_index = 95; max_sprite_index >= 0; max_sprite_index--)
|
int x_2, code_2;
|
||||||
{
|
int x, y, rows, zoom_x, zoom_y, sprite_list_offset, sprite_index, max_sprite_index, sprite_number, sprite_y, tile, attr_and_code_offs, code, zoom_x_table_offset, gfx_offset, line_pens_offset, x_inc, sprite_line, zoom_line;
|
||||||
if (neogeo_videoram[sprite_list_offset + max_sprite_index] != 0)
|
ushort y_control, zoom_control, attr;
|
||||||
|
byte sprite_y_and_tile;
|
||||||
|
bool invert;
|
||||||
|
y = 0;
|
||||||
|
x = 0;
|
||||||
|
rows = 0;
|
||||||
|
zoom_y = 0;
|
||||||
|
zoom_x = 0;
|
||||||
|
if ((scanline & 0x01) != 0)
|
||||||
{
|
{
|
||||||
break;
|
sprite_list_offset = 0x8680;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (max_sprite_index != 95)
|
|
||||||
{
|
|
||||||
max_sprite_index = max_sprite_index + 1;
|
|
||||||
}
|
|
||||||
for (sprite_index = 0; sprite_index < max_sprite_index; sprite_index++)
|
|
||||||
{
|
|
||||||
sprite_number = neogeo_videoram[sprite_list_offset + sprite_index] & 0x1ff;
|
|
||||||
y_control = neogeo_videoram[0x8200 | sprite_number];
|
|
||||||
zoom_control = neogeo_videoram[0x8000 | sprite_number];
|
|
||||||
x_2 = neogeo_videoram[0x8400 | sprite_number];
|
|
||||||
code_2 = neogeo_videoram[sprite_number << 6];
|
|
||||||
if ((y_control & 0x40) != 0)
|
|
||||||
{
|
|
||||||
x = (x + zoom_x + 1) & 0x01ff;
|
|
||||||
zoom_x = (zoom_control >> 8) & 0x0f;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
y = 0x200 - (y_control >> 7);
|
sprite_list_offset = 0x8600;
|
||||||
x = neogeo_videoram[0x8400 | sprite_number] >> 7;
|
|
||||||
zoom_y = zoom_control & 0xff;
|
|
||||||
zoom_x = (zoom_control >> 8) & 0x0f;
|
|
||||||
rows = y_control & 0x3f;
|
|
||||||
}
|
}
|
||||||
if ((x >= 0x140) && (x <= 0x1f0))
|
for (max_sprite_index = 95; max_sprite_index >= 0; max_sprite_index--)
|
||||||
{
|
{
|
||||||
continue;
|
if (neogeo_videoram[sprite_list_offset + max_sprite_index] != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sprite_on_scanline(scanline, y, rows))
|
if (max_sprite_index != 95)
|
||||||
{
|
{
|
||||||
sprite_line = (scanline - y) & 0x1ff;
|
max_sprite_index = max_sprite_index + 1;
|
||||||
zoom_line = sprite_line & 0xff;
|
}
|
||||||
invert = ((sprite_line & 0x100) != 0) ? true : false;
|
for (sprite_index = 0; sprite_index < max_sprite_index; sprite_index++)
|
||||||
if (invert)
|
{
|
||||||
|
sprite_number = neogeo_videoram[sprite_list_offset + sprite_index] & 0x1ff;
|
||||||
|
y_control = neogeo_videoram[0x8200 | sprite_number];
|
||||||
|
zoom_control = neogeo_videoram[0x8000 | sprite_number];
|
||||||
|
x_2 = neogeo_videoram[0x8400 | sprite_number];
|
||||||
|
code_2 = neogeo_videoram[sprite_number << 6];
|
||||||
|
|
||||||
|
//sprite_number = (*(videoram + sprite_list_offset + sprite_index) & 0x1ff);
|
||||||
|
//y_control = (ushort)(*(videoram + 0x8200) | sprite_number);
|
||||||
|
//zoom_control = (ushort)(*(videoram + 0x8000) | sprite_number);
|
||||||
|
//x_2 = (ushort)(*(videoram + 0x8400) | sprite_number);
|
||||||
|
//code_2 = *(videoram + (sprite_number << 6));
|
||||||
|
|
||||||
|
if ((y_control & 0x40) != 0)
|
||||||
{
|
{
|
||||||
zoom_line ^= 0xff;
|
x = (x + zoom_x + 1) & 0x01ff;
|
||||||
}
|
zoom_x = (zoom_control >> 8) & 0x0f;
|
||||||
if (rows > 0x20)
|
|
||||||
{
|
|
||||||
zoom_line = zoom_line % ((zoom_y + 1) << 1);
|
|
||||||
if (zoom_line > zoom_y)
|
|
||||||
{
|
|
||||||
zoom_line = ((zoom_y + 1) << 1) - 1 - zoom_line;
|
|
||||||
invert = !invert;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sprite_y_and_tile = zoomyrom[(zoom_y << 8) | zoom_line];
|
|
||||||
sprite_y = sprite_y_and_tile & 0x0f;
|
|
||||||
tile = sprite_y_and_tile >> 4;
|
|
||||||
if (invert)
|
|
||||||
{
|
|
||||||
sprite_y ^= 0x0f;
|
|
||||||
tile ^= 0x1f;
|
|
||||||
}
|
|
||||||
attr_and_code_offs = (sprite_number << 6) | (tile << 1);
|
|
||||||
attr = neogeo_videoram[attr_and_code_offs + 1];
|
|
||||||
code = ((attr << 12) & 0x70000) | neogeo_videoram[attr_and_code_offs];
|
|
||||||
if (auto_animation_disabled == 0)
|
|
||||||
{
|
|
||||||
if ((attr & 0x0008) != 0)
|
|
||||||
{
|
|
||||||
code = (code & ~0x07) | (auto_animation_counter & 0x07);
|
|
||||||
}
|
|
||||||
else if ((attr & 0x0004) != 0)
|
|
||||||
{
|
|
||||||
code = (code & ~0x03) | (auto_animation_counter & 0x03);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((attr & 0x0002) != 0)
|
|
||||||
{
|
|
||||||
sprite_y ^= 0x0f;
|
|
||||||
}
|
|
||||||
zoom_x_table_offset = 0;
|
|
||||||
gfx_offset = (int)(((code << 8) | (sprite_y << 4)) & sprite_gfx_address_mask);
|
|
||||||
line_pens_offset = attr >> 8 << 4;
|
|
||||||
if ((attr & 0x0001) != 0)
|
|
||||||
{
|
|
||||||
gfx_offset = gfx_offset + 0x0f;
|
|
||||||
x_inc = -1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x_inc = 1;
|
y = 0x200 - (y_control >> 7);
|
||||||
|
//x = neogeo_videoram[0x8400 | sprite_number] >> 7;
|
||||||
|
x = x_2 >> 7;
|
||||||
|
zoom_y = zoom_control & 0xff;
|
||||||
|
zoom_x = (zoom_control >> 8) & 0x0f;
|
||||||
|
rows = y_control & 0x3f;
|
||||||
}
|
}
|
||||||
int pixel_addr_offsetx, pixel_addr_offsety;
|
|
||||||
if (x <= 0x01f0)
|
fixed (int* zoom_x_tablesPtr = &zoom_x_tables[zoom_x, 0])
|
||||||
{
|
{
|
||||||
int i;
|
int* zoom_x_tables = zoom_x_tablesPtr;
|
||||||
pixel_addr_offsetx = x + NEOGEO_HBEND;
|
|
||||||
pixel_addr_offsety = scanline;
|
if ((x >= 0x140) && (x <= 0x1f0))
|
||||||
for (i = 0; i < 0x10; i++)
|
|
||||||
{
|
{
|
||||||
if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
continue;
|
||||||
|
}
|
||||||
|
if (sprite_on_scanline(scanline, y, rows))
|
||||||
|
{
|
||||||
|
sprite_line = (scanline - y) & 0x1ff;
|
||||||
|
zoom_line = sprite_line & 0xff;
|
||||||
|
invert = ((sprite_line & 0x100) != 0) ? true : false;
|
||||||
|
if (invert)
|
||||||
{
|
{
|
||||||
if (sprite_gfx[gfx_offset] != 0)
|
zoom_line ^= 0xff;
|
||||||
{
|
|
||||||
Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
|
||||||
}
|
|
||||||
pixel_addr_offsetx++;
|
|
||||||
}
|
}
|
||||||
zoom_x_table_offset++;
|
if (rows > 0x20)
|
||||||
gfx_offset += x_inc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int x_save = x;
|
|
||||||
pixel_addr_offsetx = NEOGEO_HBEND;
|
|
||||||
pixel_addr_offsety = scanline;
|
|
||||||
for (i = 0; i < 0x10; i++)
|
|
||||||
{
|
|
||||||
if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
|
||||||
{
|
{
|
||||||
if (x >= 0x200)
|
zoom_line = zoom_line % ((zoom_y + 1) << 1);
|
||||||
|
if (zoom_line > zoom_y)
|
||||||
{
|
{
|
||||||
if (sprite_gfx[gfx_offset] != 0)
|
zoom_line = ((zoom_y + 1) << 1) - 1 - zoom_line;
|
||||||
|
invert = !invert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sprite_y_and_tile = zoomyrom[(zoom_y << 8) | zoom_line];
|
||||||
|
sprite_y = sprite_y_and_tile & 0x0f;
|
||||||
|
tile = sprite_y_and_tile >> 4;
|
||||||
|
if (invert)
|
||||||
|
{
|
||||||
|
sprite_y ^= 0x0f;
|
||||||
|
tile ^= 0x1f;
|
||||||
|
}
|
||||||
|
attr_and_code_offs = (sprite_number << 6) | (tile << 1);
|
||||||
|
attr = neogeo_videoram[attr_and_code_offs + 1];
|
||||||
|
code = ((attr << 12) & 0x70000) | neogeo_videoram[attr_and_code_offs];
|
||||||
|
if (auto_animation_disabled == 0)
|
||||||
|
{
|
||||||
|
if ((attr & 0x0008) != 0)
|
||||||
|
{
|
||||||
|
code = (code & ~0x07) | (auto_animation_counter & 0x07);
|
||||||
|
}
|
||||||
|
else if ((attr & 0x0004) != 0)
|
||||||
|
{
|
||||||
|
code = (code & ~0x03) | (auto_animation_counter & 0x03);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((attr & 0x0002) != 0)
|
||||||
|
{
|
||||||
|
sprite_y ^= 0x0f;
|
||||||
|
}
|
||||||
|
zoom_x_table_offset = 0;
|
||||||
|
gfx_offset = (int)(((code << 8) | (sprite_y << 4)) & sprite_gfx_address_mask);
|
||||||
|
line_pens_offset = attr >> 8 << 4;
|
||||||
|
if ((attr & 0x0001) != 0)
|
||||||
|
{
|
||||||
|
gfx_offset = gfx_offset + 0x0f;
|
||||||
|
x_inc = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x_inc = 1;
|
||||||
|
}
|
||||||
|
int pixel_addr_offsetx, pixel_addr_offsety;
|
||||||
|
if (x <= 0x01f0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
pixel_addr_offsetx = x + NEOGEO_HBEND;
|
||||||
|
pixel_addr_offsety = scanline;
|
||||||
|
for (i = 0; i < 0x10; i++)
|
||||||
|
{
|
||||||
|
//if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
||||||
|
if (zoom_x_tables[zoom_x_table_offset] != 0)
|
||||||
{
|
{
|
||||||
Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
//if (sprite_gfx[gfx_offset] != 0)
|
||||||
|
if (spriteGfx[gfx_offset] != 0)
|
||||||
|
{
|
||||||
|
//Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
||||||
|
bitmapbase[pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + spriteGfx[gfx_offset]];
|
||||||
|
}
|
||||||
|
pixel_addr_offsetx++;
|
||||||
}
|
}
|
||||||
pixel_addr_offsetx++;
|
zoom_x_table_offset++;
|
||||||
|
gfx_offset += x_inc;
|
||||||
}
|
}
|
||||||
x++;
|
|
||||||
}
|
}
|
||||||
zoom_x_table_offset++;
|
else
|
||||||
gfx_offset += x_inc;
|
{
|
||||||
|
int i;
|
||||||
|
int x_save = x;
|
||||||
|
pixel_addr_offsetx = NEOGEO_HBEND;
|
||||||
|
pixel_addr_offsety = scanline;
|
||||||
|
for (i = 0; i < 0x10; i++)
|
||||||
|
{
|
||||||
|
//if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
||||||
|
if (zoom_x_tables[zoom_x_table_offset] != 0)
|
||||||
|
{
|
||||||
|
if (x >= 0x200)
|
||||||
|
{
|
||||||
|
//if (sprite_gfx[gfx_offset] != 0)
|
||||||
|
if (spriteGfx[gfx_offset] != 0)
|
||||||
|
{
|
||||||
|
//Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
||||||
|
bitmapbase[pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + spriteGfx[gfx_offset]];
|
||||||
|
}
|
||||||
|
pixel_addr_offsetx++;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
zoom_x_table_offset++;
|
||||||
|
gfx_offset += x_inc;
|
||||||
|
}
|
||||||
|
x = x_save;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
x = x_save;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//private static void draw_sprites(int iBitmap, int scanline)
|
||||||
|
//{
|
||||||
|
// int x_2, code_2;
|
||||||
|
// int x, y, rows, zoom_x, zoom_y, sprite_list_offset, sprite_index, max_sprite_index, sprite_number, sprite_y, tile, attr_and_code_offs, code, zoom_x_table_offset, gfx_offset, line_pens_offset, x_inc, sprite_line, zoom_line;
|
||||||
|
// ushort y_control, zoom_control, attr;
|
||||||
|
// byte sprite_y_and_tile;
|
||||||
|
// bool invert;
|
||||||
|
// y = 0;
|
||||||
|
// x = 0;
|
||||||
|
// rows = 0;
|
||||||
|
// zoom_y = 0;
|
||||||
|
// zoom_x = 0;
|
||||||
|
// if ((scanline & 0x01) != 0)
|
||||||
|
// {
|
||||||
|
// sprite_list_offset = 0x8680;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// sprite_list_offset = 0x8600;
|
||||||
|
// }
|
||||||
|
// for (max_sprite_index = 95; max_sprite_index >= 0; max_sprite_index--)
|
||||||
|
// {
|
||||||
|
// if (neogeo_videoram[sprite_list_offset + max_sprite_index] != 0)
|
||||||
|
// {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (max_sprite_index != 95)
|
||||||
|
// {
|
||||||
|
// max_sprite_index = max_sprite_index + 1;
|
||||||
|
// }
|
||||||
|
// for (sprite_index = 0; sprite_index < max_sprite_index; sprite_index++)
|
||||||
|
// {
|
||||||
|
// sprite_number = neogeo_videoram[sprite_list_offset + sprite_index] & 0x1ff;
|
||||||
|
// y_control = neogeo_videoram[0x8200 | sprite_number];
|
||||||
|
// zoom_control = neogeo_videoram[0x8000 | sprite_number];
|
||||||
|
// x_2 = neogeo_videoram[0x8400 | sprite_number];
|
||||||
|
// code_2 = neogeo_videoram[sprite_number << 6];
|
||||||
|
// if ((y_control & 0x40) != 0)
|
||||||
|
// {
|
||||||
|
// x = (x + zoom_x + 1) & 0x01ff;
|
||||||
|
// zoom_x = (zoom_control >> 8) & 0x0f;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// y = 0x200 - (y_control >> 7);
|
||||||
|
// x = neogeo_videoram[0x8400 | sprite_number] >> 7;
|
||||||
|
// zoom_y = zoom_control & 0xff;
|
||||||
|
// zoom_x = (zoom_control >> 8) & 0x0f;
|
||||||
|
// rows = y_control & 0x3f;
|
||||||
|
// }
|
||||||
|
// if ((x >= 0x140) && (x <= 0x1f0))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (sprite_on_scanline(scanline, y, rows))
|
||||||
|
// {
|
||||||
|
// sprite_line = (scanline - y) & 0x1ff;
|
||||||
|
// zoom_line = sprite_line & 0xff;
|
||||||
|
// invert = ((sprite_line & 0x100) != 0) ? true : false;
|
||||||
|
// if (invert)
|
||||||
|
// {
|
||||||
|
// zoom_line ^= 0xff;
|
||||||
|
// }
|
||||||
|
// if (rows > 0x20)
|
||||||
|
// {
|
||||||
|
// zoom_line = zoom_line % ((zoom_y + 1) << 1);
|
||||||
|
// if (zoom_line > zoom_y)
|
||||||
|
// {
|
||||||
|
// zoom_line = ((zoom_y + 1) << 1) - 1 - zoom_line;
|
||||||
|
// invert = !invert;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// sprite_y_and_tile = zoomyrom[(zoom_y << 8) | zoom_line];
|
||||||
|
// sprite_y = sprite_y_and_tile & 0x0f;
|
||||||
|
// tile = sprite_y_and_tile >> 4;
|
||||||
|
// if (invert)
|
||||||
|
// {
|
||||||
|
// sprite_y ^= 0x0f;
|
||||||
|
// tile ^= 0x1f;
|
||||||
|
// }
|
||||||
|
// attr_and_code_offs = (sprite_number << 6) | (tile << 1);
|
||||||
|
// attr = neogeo_videoram[attr_and_code_offs + 1];
|
||||||
|
// code = ((attr << 12) & 0x70000) | neogeo_videoram[attr_and_code_offs];
|
||||||
|
// if (auto_animation_disabled == 0)
|
||||||
|
// {
|
||||||
|
// if ((attr & 0x0008) != 0)
|
||||||
|
// {
|
||||||
|
// code = (code & ~0x07) | (auto_animation_counter & 0x07);
|
||||||
|
// }
|
||||||
|
// else if ((attr & 0x0004) != 0)
|
||||||
|
// {
|
||||||
|
// code = (code & ~0x03) | (auto_animation_counter & 0x03);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if ((attr & 0x0002) != 0)
|
||||||
|
// {
|
||||||
|
// sprite_y ^= 0x0f;
|
||||||
|
// }
|
||||||
|
// zoom_x_table_offset = 0;
|
||||||
|
// gfx_offset = (int)(((code << 8) | (sprite_y << 4)) & sprite_gfx_address_mask);
|
||||||
|
// line_pens_offset = attr >> 8 << 4;
|
||||||
|
// if ((attr & 0x0001) != 0)
|
||||||
|
// {
|
||||||
|
// gfx_offset = gfx_offset + 0x0f;
|
||||||
|
// x_inc = -1;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// x_inc = 1;
|
||||||
|
// }
|
||||||
|
// int pixel_addr_offsetx, pixel_addr_offsety;
|
||||||
|
// if (x <= 0x01f0)
|
||||||
|
// {
|
||||||
|
// int i;
|
||||||
|
// pixel_addr_offsetx = x + NEOGEO_HBEND;
|
||||||
|
// pixel_addr_offsety = scanline;
|
||||||
|
// for (i = 0; i < 0x10; i++)
|
||||||
|
// {
|
||||||
|
// if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
||||||
|
// {
|
||||||
|
// if (sprite_gfx[gfx_offset] != 0)
|
||||||
|
// {
|
||||||
|
// Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
||||||
|
// }
|
||||||
|
// pixel_addr_offsetx++;
|
||||||
|
// }
|
||||||
|
// zoom_x_table_offset++;
|
||||||
|
// gfx_offset += x_inc;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// int i;
|
||||||
|
// int x_save = x;
|
||||||
|
// pixel_addr_offsetx = NEOGEO_HBEND;
|
||||||
|
// pixel_addr_offsety = scanline;
|
||||||
|
// for (i = 0; i < 0x10; i++)
|
||||||
|
// {
|
||||||
|
// if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
|
||||||
|
// {
|
||||||
|
// if (x >= 0x200)
|
||||||
|
// {
|
||||||
|
// if (sprite_gfx[gfx_offset] != 0)
|
||||||
|
// {
|
||||||
|
// Video.bitmapbaseN[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
|
||||||
|
// }
|
||||||
|
// pixel_addr_offsetx++;
|
||||||
|
// }
|
||||||
|
// x++;
|
||||||
|
// }
|
||||||
|
// zoom_x_table_offset++;
|
||||||
|
// gfx_offset += x_inc;
|
||||||
|
// }
|
||||||
|
// x = x_save;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
private static void parse_sprites(int scanline)
|
private static void parse_sprites(int scanline)
|
||||||
{
|
{
|
||||||
ushort sprite_number, y_control;
|
ushort sprite_number, y_control;
|
||||||
|
@ -199,47 +199,132 @@ namespace MAME.Core
|
|||||||
ycnt++;
|
ycnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static void draw_sprites(int priority)
|
unsafe private static void draw_sprites(int priority)
|
||||||
{
|
{
|
||||||
while (pgm_sprite_source_offset < 0x500)
|
fixed (ushort* pSpriteBuffer = &pgm_spritebufferram[0])
|
||||||
|
fixed (byte* pVideoRegs = &pgm_videoregs[0])
|
||||||
{
|
{
|
||||||
int xpos = pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x07ff;
|
ushort* spritePtr = pSpriteBuffer + pgm_sprite_source_offset;
|
||||||
int ypos = pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x03ff;
|
int offset = 0;
|
||||||
int xzom = (pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x7800) >> 11;
|
|
||||||
int xgrow = (pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x8000) >> 15;
|
while (pgm_sprite_source_offset < 0x500)
|
||||||
int yzom = (pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x7800) >> 11;
|
|
||||||
int ygrow = (pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x8000) >> 15;
|
|
||||||
int palt = (pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x1f00) >> 8;
|
|
||||||
int flip = (pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x6000) >> 13;
|
|
||||||
int boff = ((pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x007f) << 16) | (pgm_spritebufferram[pgm_sprite_source_offset + 3] & 0xffff);
|
|
||||||
int wide = (pgm_spritebufferram[pgm_sprite_source_offset + 4] & 0x7e00) >> 9;
|
|
||||||
int high = pgm_spritebufferram[pgm_sprite_source_offset + 4] & 0x01ff;
|
|
||||||
int pri = (pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x0080) >> 7;
|
|
||||||
int xzoom, yzoom;
|
|
||||||
int pgm_sprite_zoomtable_offset = 0x1000;
|
|
||||||
if (xgrow != 0)
|
|
||||||
{
|
{
|
||||||
xzom = 0x10 - xzom;
|
// 读取数据
|
||||||
|
ushort* spriteData = (ushort*)spritePtr;
|
||||||
|
int xpos = spriteData[0] & 0x07FF;
|
||||||
|
int ypos = spriteData[1] & 0x03FF;
|
||||||
|
int xzom = (spriteData[0] & 0x7800) >> 11;
|
||||||
|
int xgrow = (spriteData[0] & 0x8000) >> 15;
|
||||||
|
int yzom = (spriteData[1] & 0x7800) >> 11;
|
||||||
|
int ygrow = (spriteData[1] & 0x8000) >> 15;
|
||||||
|
ushort* spriteData2 = (ushort*)(spritePtr + 4);
|
||||||
|
int palt = (spriteData2[0] & 0x1F00) >> 8;
|
||||||
|
int flip = (spriteData2[0] & 0x6000) >> 13;
|
||||||
|
int boff = ((spriteData2[0] & 0x007F) << 16) | spriteData2[1];
|
||||||
|
ushort* spriteData3 = (ushort*)(spritePtr + 6);
|
||||||
|
int wide = (spriteData3[0] & 0x7E00) >> 9;
|
||||||
|
int high = spriteData3[0] & 0x01FF;
|
||||||
|
int pri = (spriteData2[0] & 0x0080) >> 7;
|
||||||
|
int pgm_sprite_zoomtable_offset = 0x1000;
|
||||||
|
// 处理缩放
|
||||||
|
int xzoom, yzoom;
|
||||||
|
int* zoomTablePtr = (int*)(pVideoRegs + pgm_sprite_zoomtable_offset);
|
||||||
|
if (xgrow != 0)
|
||||||
|
{
|
||||||
|
xzom = 0x10 - xzom;
|
||||||
|
}
|
||||||
|
if (ygrow != 0)
|
||||||
|
{
|
||||||
|
yzom = 0x10 - yzom;
|
||||||
|
}
|
||||||
|
xzoom = zoomTablePtr[xzom * 4] * 0x10000 + zoomTablePtr[xzom * 4 + 1] * 0x100 + zoomTablePtr[xzom * 4 + 2];
|
||||||
|
yzoom = zoomTablePtr[yzom * 4] * 0x10000 + zoomTablePtr[yzom * 4 + 1] * 0x100 + zoomTablePtr[yzom * 4 + 2];
|
||||||
|
|
||||||
|
// 调整偏移和边界检查
|
||||||
|
boff *= 2;
|
||||||
|
if (xpos > 0x3FF)
|
||||||
|
xpos -= 0x800;
|
||||||
|
if (ypos > 0x1FF)
|
||||||
|
ypos -= 0x400;
|
||||||
|
if (high == 0)
|
||||||
|
break;
|
||||||
|
if ((priority == 1) && (pri == 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 调用绘制函数(注意:这个函数也需要被修改为接受指针或适当的参数类型)
|
||||||
|
draw_sprite_new_zoomed(wide, high, xpos, ypos, palt, boff, flip, xzoom, xgrow, yzoom, ygrow);
|
||||||
|
|
||||||
|
// 移动到下一个精灵
|
||||||
|
spritePtr += 10; // 每个精灵占用5个ushort,即10个字节
|
||||||
|
pgm_sprite_source_offset += 5; // 假设pgm_sprite_source_offset是以ushort为单位递增的
|
||||||
|
|
||||||
|
// 注意:这里我们直接通过指针移动,因此不需要再次访问数组来更新pgm_sprite_source_offset对应的值
|
||||||
}
|
}
|
||||||
if (ygrow != 0)
|
|
||||||
{
|
|
||||||
yzom = 0x10 - yzom;
|
|
||||||
}
|
|
||||||
xzoom = ((pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 1]) << 16) | (pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 2] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 3]);
|
|
||||||
yzoom = ((pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 1]) << 16) | (pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 2] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 3]);
|
|
||||||
boff *= 2;
|
|
||||||
if (xpos > 0x3ff)
|
|
||||||
xpos -= 0x800;
|
|
||||||
if (ypos > 0x1ff)
|
|
||||||
ypos -= 0x400;
|
|
||||||
if (high == 0)
|
|
||||||
break;
|
|
||||||
if ((priority == 1) && (pri == 0))
|
|
||||||
break;
|
|
||||||
draw_sprite_new_zoomed(wide, high, xpos, ypos, palt, boff, flip, xzoom, xgrow, yzoom, ygrow);
|
|
||||||
pgm_sprite_source_offset += 5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//private static void draw_sprites(int priority)
|
||||||
|
//{
|
||||||
|
// while (pgm_sprite_source_offset < 0x500)
|
||||||
|
// {
|
||||||
|
// //用Span优化
|
||||||
|
// Span<ushort> span_pgm_spritebufferram = pgm_spritebufferram.AsSpan();
|
||||||
|
// int xpos = span_pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x07ff;
|
||||||
|
// int ypos = span_pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x03ff;
|
||||||
|
// int xzom = (span_pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x7800) >> 11;
|
||||||
|
// int xgrow = (span_pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x8000) >> 15;
|
||||||
|
// int yzom = (span_pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x7800) >> 11;
|
||||||
|
// int ygrow = (span_pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x8000) >> 15;
|
||||||
|
// int palt = (span_pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x1f00) >> 8;
|
||||||
|
// int flip = (span_pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x6000) >> 13;
|
||||||
|
// int boff = ((span_pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x007f) << 16) | (span_pgm_spritebufferram[pgm_sprite_source_offset + 3] & 0xffff);
|
||||||
|
// int wide = (span_pgm_spritebufferram[pgm_sprite_source_offset + 4] & 0x7e00) >> 9;
|
||||||
|
// int high = span_pgm_spritebufferram[pgm_sprite_source_offset + 4] & 0x01ff;
|
||||||
|
// int pri = (span_pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x0080) >> 7;
|
||||||
|
|
||||||
|
|
||||||
|
// //int xpos = pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x07ff;
|
||||||
|
// //int ypos = pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x03ff;
|
||||||
|
// //int xzom = (pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x7800) >> 11;
|
||||||
|
// //int xgrow = (pgm_spritebufferram[pgm_sprite_source_offset + 0] & 0x8000) >> 15;
|
||||||
|
// //int yzom = (pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x7800) >> 11;
|
||||||
|
// //int ygrow = (pgm_spritebufferram[pgm_sprite_source_offset + 1] & 0x8000) >> 15;
|
||||||
|
// //int palt = (pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x1f00) >> 8;
|
||||||
|
// //int flip = (pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x6000) >> 13;
|
||||||
|
// //int boff = ((pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x007f) << 16) | (pgm_spritebufferram[pgm_sprite_source_offset + 3] & 0xffff);
|
||||||
|
// //int wide = (pgm_spritebufferram[pgm_sprite_source_offset + 4] & 0x7e00) >> 9;
|
||||||
|
// //int high = pgm_spritebufferram[pgm_sprite_source_offset + 4] & 0x01ff;
|
||||||
|
// //int pri = (pgm_spritebufferram[pgm_sprite_source_offset + 2] & 0x0080) >> 7;
|
||||||
|
|
||||||
|
// int xzoom, yzoom;
|
||||||
|
// int pgm_sprite_zoomtable_offset = 0x1000;
|
||||||
|
// if (xgrow != 0)
|
||||||
|
// {
|
||||||
|
// xzom = 0x10 - xzom;
|
||||||
|
// }
|
||||||
|
// if (ygrow != 0)
|
||||||
|
// {
|
||||||
|
// yzom = 0x10 - yzom;
|
||||||
|
// }
|
||||||
|
// Span<byte> span_pgm_videoregs = pgm_videoregs.AsSpan();
|
||||||
|
// xzoom = ((span_pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4] * 0x100 + span_pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 1]) << 16) | (span_pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 2] * 0x100 + span_pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 3]);
|
||||||
|
// yzoom = ((span_pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4] * 0x100 + span_pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 1]) << 16) | (span_pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 2] * 0x100 + span_pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 3]);
|
||||||
|
|
||||||
|
// //xzoom = ((pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 1]) << 16) | (pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 2] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + xzom * 4 + 3]);
|
||||||
|
// //yzoom = ((pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 1]) << 16) | (pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 2] * 0x100 + pgm_videoregs[pgm_sprite_zoomtable_offset + yzom * 4 + 3]);
|
||||||
|
// boff *= 2;
|
||||||
|
// if (xpos > 0x3ff)
|
||||||
|
// xpos -= 0x800;
|
||||||
|
// if (ypos > 0x1ff)
|
||||||
|
// ypos -= 0x400;
|
||||||
|
// if (high == 0)
|
||||||
|
// break;
|
||||||
|
// if ((priority == 1) && (pri == 0))
|
||||||
|
// break;
|
||||||
|
// draw_sprite_new_zoomed(wide, high, xpos, ypos, palt, boff, flip, xzoom, xgrow, yzoom, ygrow);
|
||||||
|
// pgm_sprite_source_offset += 5;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
private static void pgm_tx_videoram_w(int offset, byte data)
|
private static void pgm_tx_videoram_w(int offset, byte data)
|
||||||
{
|
{
|
||||||
int col, row;
|
int col, row;
|
||||||
|
@ -115,6 +115,8 @@ namespace MAME.Core
|
|||||||
i1++;
|
i1++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//TODO 移动到这里,但是大小,还需要考虑
|
||||||
|
static short[] sample_data = new short[10000];
|
||||||
public static void okim6295_update(int offset, int length)
|
public static void okim6295_update(int offset, int length)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -124,7 +126,8 @@ namespace MAME.Core
|
|||||||
}
|
}
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
short[] sample_data = new short[10000];
|
//不每次new,避免GC,排除问题。待验证影响
|
||||||
|
//short[] sample_data = new short[10000];
|
||||||
int remaining = length;
|
int remaining = length;
|
||||||
while (remaining != 0)
|
while (remaining != 0)
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user