mirror of
https://github.com/lscharen/iigs-sprite-compiler.git
synced 2025-01-29 10:31:33 +00:00
Add a 16-bit word operation and unit test
This commit is contained in:
parent
ff48fefcd4
commit
de3754e91e
@ -4,6 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using SpriteCompiler.Problem;
|
||||
using SpriteCompiler.AI;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpriteCompiler.Test
|
||||
{
|
||||
@ -50,13 +51,9 @@ namespace SpriteCompiler.Test
|
||||
Assert.AreEqual(14, (int)solution.Last().PathCost);
|
||||
|
||||
// Write out the solution
|
||||
foreach (var step in solution.Skip(1))
|
||||
{
|
||||
Trace.WriteLine(step.Action.ToString());
|
||||
}
|
||||
WriteOutSolution(solution);
|
||||
}
|
||||
|
||||
/*
|
||||
[TestMethod]
|
||||
public void TestSingleWordSprite()
|
||||
{
|
||||
@ -65,11 +62,31 @@ namespace SpriteCompiler.Test
|
||||
var search = SpriteGeneratorSearchProblem.Create();
|
||||
|
||||
// Act : solve the problem
|
||||
var solution = search.Search(problem, new SpriteGeneratorState());
|
||||
var solution = search.Search(problem, new SpriteGeneratorState(new byte[] { 0xAA, 0x55 }));
|
||||
|
||||
// Assert : The initial state IS the goal state
|
||||
Assert.AreEqual(1, solution.Count());
|
||||
// Assert
|
||||
//
|
||||
// The fastest way to draw a single word at the current location should be
|
||||
//
|
||||
// TCS
|
||||
// LDA #$55AA
|
||||
// STA 0,s = 10 cycles
|
||||
|
||||
Assert.AreEqual(3, solution.Count());
|
||||
Assert.AreEqual(10, (int)solution.Last().PathCost);
|
||||
|
||||
// Write out the solution
|
||||
WriteOutSolution(solution);
|
||||
}
|
||||
|
||||
private void WriteOutSolution(IEnumerable<SpriteGeneratorSearchNode> solution)
|
||||
{
|
||||
foreach (var step in solution.Skip(1))
|
||||
{
|
||||
Trace.WriteLine(step.Action.ToString());
|
||||
}
|
||||
|
||||
Trace.WriteLine(string.Format("; Total Cost = {0} cycles", (int)solution.Last().PathCost));
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -118,4 +118,31 @@ namespace SpriteCompiler.Problem
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class STACK_REL_16_BIT_IMMEDIATE_STORE : CodeSequence
|
||||
{
|
||||
private readonly ushort value;
|
||||
private readonly byte offset;
|
||||
|
||||
public STACK_REL_16_BIT_IMMEDIATE_STORE(ushort value, byte offset) : base(8) { this.value = value; this.offset = offset; }
|
||||
|
||||
public override SpriteGeneratorState Apply(SpriteGeneratorState state)
|
||||
{
|
||||
return state.Clone(_ =>
|
||||
{
|
||||
_.A = _.A.LoadConstant(value);
|
||||
_.RemoveByte((ushort)(offset + _.S.Value));
|
||||
_.RemoveByte((ushort)(offset + _.S.Value + 1));
|
||||
});
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Join("\n",
|
||||
FormatLine("", "LDA", "#$" + value.ToString("X4"), "3 cycles"),
|
||||
FormatLine("", "STA", offset.ToString("X2") + ",s", "5 cycles")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -242,6 +242,34 @@ namespace SpriteCompiler.Problem
|
||||
actions.Add(new SHORT_M());
|
||||
|
||||
// Add any possible 16-bit data manipulations
|
||||
if (state.S.IsScreenOffset)
|
||||
{
|
||||
var addr = state.S.Value;
|
||||
|
||||
// Look for consecutive bytes
|
||||
var local = state.Bytes.Where(WithinRangeOf(addr, 257)).ToList(); // 16-bit value can extend to the 256th byte
|
||||
var words = local
|
||||
.Skip(1)
|
||||
.Select((x, i) => new { High = x, Low = local[i] })
|
||||
.Where(p => p.Low.Offset == (p.High.Offset - 1))
|
||||
.ToList();
|
||||
|
||||
foreach (var word in words)
|
||||
{
|
||||
var offset = (byte)(word.Low.Offset - addr);
|
||||
var data = (ushort)(word.Low.Data + (word.High.Data << 8));
|
||||
actions.Add(new STACK_REL_16_BIT_IMMEDIATE_STORE(data, offset));
|
||||
|
||||
}
|
||||
|
||||
// We can LDA #$XXXX / STA X,s for any values within 256 bytes of the current address
|
||||
foreach (var datum in state.Bytes.Where(WithinRangeOf(addr, 256)))
|
||||
{
|
||||
var offset = (byte)(datum.Offset - addr);
|
||||
actions.Add(new STACK_REL_8_BIT_IMMEDIATE_STORE(datum.Data, offset));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,8 +280,8 @@ namespace SpriteCompiler.Problem
|
||||
{
|
||||
var addr = state.S.Value;
|
||||
|
||||
// We can LDA #$XX / STA X,s for any values within 256 bytes of the curren address
|
||||
foreach (var datum in state.Bytes.Where(x => (x.Offset - addr) < 255))
|
||||
// We can LDA #$XX / STA X,s for any values within 256 bytes of the current address
|
||||
foreach (var datum in state.Bytes.Where(WithinRangeOf(addr, 256)))
|
||||
{
|
||||
var offset = datum.Offset - addr;
|
||||
actions.Add(new STACK_REL_8_BIT_IMMEDIATE_STORE(datum.Data, (byte)offset));
|
||||
@ -264,6 +292,11 @@ namespace SpriteCompiler.Problem
|
||||
// Run through the actions to create a dictionary
|
||||
return actions.ToDictionary(x => x, x => x.Apply(state));
|
||||
}
|
||||
|
||||
private Func<SpriteByte, bool> WithinRangeOf(int addr, int range)
|
||||
{
|
||||
return x => (x.Offset >= addr) && ((x.Offset - addr) < range);
|
||||
}
|
||||
}
|
||||
|
||||
public class SpriteGeneratorHeuristicFunction : IHeuristicFunction<SpriteGeneratorState, IntegerPathCost>
|
||||
|
Loading…
x
Reference in New Issue
Block a user