Beispiel #1
0
        public void TestSingleByteWithMask()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new byte[] { 0x00, 0x11 };
            var mask = new byte[] { 0xFF, 0x00 };

            var initialState     = SpriteGeneratorState.Init(data, mask);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert
            //
            // Solution should be same as regular single-byte sprite, except
            // the store happens at offset 1, instead of 0.

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(5, solution.Count());
            Assert.AreEqual(14, (int)solution.Last().PathCost);
        }
Beispiel #2
0
        public void TestSingleByteSprite()
        {
            Trace.WriteLine("Testing a sprite with just one byte");

            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new byte[] { 0xAA };

            var initialState     = SpriteGeneratorState.Init(data);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert
            //
            // The fastest way to draw a single byte at the current location should be
            //
            // TCS
            // SHORT A
            // LDA #$AA
            // PHA
            // LONG A     = 13 cycles

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(5, solution.Count());
            Assert.AreEqual(13, (int)solution.Last().PathCost);
        }
Beispiel #3
0
        public void TestSingleWordSprite()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new byte[] { 0xAA, 0x55 };

            var initialState     = SpriteGeneratorState.Init(data);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert
            //
            // The fastest way to draw a single word at the current location should be
            //
            // TCS
            // LDA #$55AA
            // STA 0,s     = 10 cycles
            //
            // Alternate
            //
            // ADC #1
            // TCS
            // PEA #$55AA  = 10 cycles

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(3, solution.Count());
            Assert.AreEqual(10, (int)solution.Last().PathCost);
        }
Beispiel #4
0
        public void TestConsecutiveWordSpriteWithMask()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new byte[] { 0x01, 0x11, 0x22, 0x11, 0x33 };
            var mask = new byte[] { 0xF0, 0x00, 0x00, 0x00, 0x00 };

            var initialState     = SpriteGeneratorState.Init(data, mask);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert
            //
            // The fastest way to render this data should be
            //
            // ADC #4
            // TCS
            // PEA $3311
            // PEA $2211
            // LDA 0,s
            // AND #$00F0
            // ORA #$1101
            // STA 0,s   = 31 cycles

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(31, (int)solution.Last().PathCost);
        }
Beispiel #5
0
        public void TestConsecutiveWordSprite()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new byte[] { 0xAA, 0x55, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };

            var initialState     = SpriteGeneratorState.Init(data);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert
            //
            // The fastest way to draw a consecutive words should be
            //
            // ADC #7
            // TCS
            // PEA $6655
            // PEA $4433
            // PEA $2211
            // PEA $55AA   = 25 cycles

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(6, solution.Count());
            Assert.AreEqual(25, (int)solution.Last().PathCost);
        }
Beispiel #6
0
        public void TestSinglePixelMask()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new byte[] { 0x01, 0x11 };
            var mask = new byte[] { 0xF0, 0x00 };

            var initialState     = SpriteGeneratorState.Init(data, mask);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert
            //
            // Solution should be a single 16-bit RMW
            //
            // TCS
            // LDA 0,s
            // AND #$00F0
            // ORA #$1101
            // STA 0,s     = 18 cycles

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(18, (int)solution.Last().PathCost);
        }
Beispiel #7
0
        public void TestLines_1_To_2()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();
            var sprite  = new List <SpriteByte>
            {
                new SpriteByte(0x11, 0x00, 3),
                new SpriteByte(0x11, 0x00, 4),
                new SpriteByte(0x10, 0x0F, 5),

                new SpriteByte(0x11, 0x00, 162),
                new SpriteByte(0x11, 0x00, 163),
                new SpriteByte(0x11, 0x00, 164),
                new SpriteByte(0x20, 0x0F, 165),
            };

            // Act : solve the problem
            var initialState     = SpriteGeneratorState.Init(sprite);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert : The initial state IS the goal state (47 cycles is the currrent best solution)
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
        }
Beispiel #8
0
        public void TestOverlappingWrite()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new byte[] { 0x11, 0x22, 0x22 };

            var initialState     = SpriteGeneratorState.Init(data);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert
            //
            // Solution should be 18 cycles
            //
            // TCS
            // LDA #$2211
            // STA 0,s
            // LDA #$2222
            // STA 1,s    = 18 cycles

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(18, (int)solution.Last().PathCost);
        }
Beispiel #9
0
        public void TestThreeLineSprite()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var data = new[]
            {
                new SpriteByte(0x11, 0),
                new SpriteByte(0x11, 160),
                new SpriteByte(0x11, 320)
            };

            var initialState     = SpriteGeneratorState.Init(data);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Current best solution
            //
            //	TCS		; 2 cycles
            //	SEP	#$10	; 3 cycles
            //	LDA	#$11	; 2 cycles
            //	PHA	        ; 3 cycles
            //	STA	A1,s	; 4 cycles
            //	REP	#$10	; 3 cycles
            //	TSC		    ; 2 cycles
            //	ADC	#321	; 3 cycles
            //	TCS		    ; 2 cycles
            //	SEP	#$10	; 3 cycles
            //	LDA	#$11	; 2 cycles
            //	PHA         ; 3 cycles
            //	REP	#$10	; 3 cycles
            //; Total Cost = 35 cycles
            //
            // Once other register caching becomes available, this should be able to be improved to
            //
            //	TCS		    ; 2 cycles
            //	SEP	#$20	; 3 cycles
            //	LDX	#$11	; 2 cycles
            //	PHX	        ; 3 cycles
            //  ADC #160    ; 3 cycles
            //  TCS         ; 2 cycles
            //  PHX         ; 3 cycles
            //  ADC #161    ; 3 cycles
            //  TCS         ; 2 cycles
            //  PHX         ; 3 cycles
            //  REP #$20    ; 3 cycles
            //; Total Cost = 29 cycles

            // Write out the solution
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(35, (int)solution.Last().PathCost);
        }
Beispiel #10
0
        public void TestInitialState()
        {
            var data = new[]
            {
                new SpriteByte(0x11, 0),
                new SpriteByte(0x11, 160),
                new SpriteByte(0x11, 320)
            };

            var state      = SpriteGeneratorState.Init(data);
            var successors = successor.Successors(state);

            // Should pick only the first data item
            Assert.AreEqual(1, successors.Count());
            Assert.AreEqual(successors.First().Item1.GetType(), typeof(MOVE_STACK));
        }
Beispiel #11
0
        public void TestStateEquivalence()
        {
            // States are used in HashSet, so we need to
            // test that two instances of the same state
            // are recognized as equivalent
            var state1 = new SpriteGeneratorState();
            var state2 = new SpriteGeneratorState();

            Assert.AreEqual(state1, state2);

            var set = new HashSet <SpriteGeneratorState>();

            set.Add(state1);

            Assert.IsTrue(set.Contains(state2));
        }
        public void TestSmallGap()
        {
            // Create a test with $XX -- -- $XX with the Accumulator loaded with $XX. Optimal code is
            //                     ^
            // STA 3,s
            // PHA     = 7 cycles

            var state = SpriteGeneratorState.Init(new[] { new SpriteByte(0x11, 0), new SpriteByte(0x11, 3) });

            state.A = Register.Constant(0x0011);
            state.S = Register.INITIAL_OFFSET;
            state.P = SpriteGeneratorState.LONG_I;

            var h = heuristic.Eval(state);

            h.Should().BeLessOrEqualTo(7);
        }
Beispiel #13
0
        public void TestEmptySprite()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();

            // Act : solve the problem
            var initialState     = SpriteGeneratorState.Init(Enumerable.Empty <SpriteByte>());
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert : The initial state IS the goal state
            WriteOutSolution(solution, initialHeuristic);

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
            Assert.AreEqual(1, solution.Count());
        }
Beispiel #14
0
        public void TestFirstLine()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create();
            var sprite  = new List <SpriteByte>
            {
                new SpriteByte(0x11, 0x00, 3),
                new SpriteByte(0x11, 0x00, 4),
                new SpriteByte(0x10, 0x0F, 5)
            };

            // Act : solve the problem
            var solution = search.Search(problem, SpriteGeneratorState.Init(sprite));

            // Assert : The initial state IS the goal state
            WriteOutSolution(solution);
        }
Beispiel #15
0
        public void TestLines_1_To_4()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create(200); // max budget of 200 cycles
            var sprite  = new List <SpriteByte>
            {
                new SpriteByte(0x11, 0x00, 3),
                new SpriteByte(0x11, 0x00, 4),
                new SpriteByte(0x10, 0x0F, 5),

                new SpriteByte(0x11, 0x00, 162),
                new SpriteByte(0x11, 0x00, 163),
                new SpriteByte(0x11, 0x00, 164),
                new SpriteByte(0x20, 0x0F, 165),

                new SpriteByte(0x01, 0xF0, 321),
                new SpriteByte(0x11, 0x00, 322),
                new SpriteByte(0x11, 0x00, 323),
                new SpriteByte(0x12, 0x00, 324),
                new SpriteByte(0x20, 0x0F, 325),

                new SpriteByte(0x01, 0xF0, 481),
                new SpriteByte(0x11, 0x00, 482),
                new SpriteByte(0x11, 0x00, 483),
                new SpriteByte(0x11, 0x00, 484),
                new SpriteByte(0x11, 0x00, 485),
                new SpriteByte(0x11, 0x00, 486)
            };

            // Act : solve the problem
            var initialState     = SpriteGeneratorState.Init(sprite);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert : The initial state IS the goal state
            WriteOutSolution(solution);
        }
Beispiel #16
0
        public void TestLines_1_To_3()
        {
            // Arrange
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = SpriteGeneratorSearchProblem.Create(100); // max budget of 100 cycles
            var sprite  = new List <SpriteByte>
            {
                new SpriteByte(0x11, 0x00, 3),
                new SpriteByte(0x11, 0x00, 4),
                new SpriteByte(0x10, 0x0F, 5),

                new SpriteByte(0x11, 0x00, 162),
                new SpriteByte(0x11, 0x00, 163),
                new SpriteByte(0x11, 0x00, 164),
                new SpriteByte(0x20, 0x0F, 165),

                new SpriteByte(0x01, 0xF0, 321),
                new SpriteByte(0x11, 0x00, 322),
                new SpriteByte(0x11, 0x00, 323),
                new SpriteByte(0x12, 0x00, 324),
                new SpriteByte(0x20, 0x0F, 325)
            };

            // Act : solve the problem
            var initialState     = SpriteGeneratorState.Init(sprite);
            var initialHeuristic = problem.Heuristic(initialState);

            var solution = search.Search(problem, initialState);

            // Assert : The initial state IS the goal state
            WriteOutSolution(solution);

            //    TCS		; 2 cycles
            //    LDA	04,s	; 5 cycles
            //    AND	#$0F00	; 3 cycles
            //    ORA	#$1011	; 3 cycles
            //    STA	04,s	; 5 cycles
            //    LDA	#$1111	; 3 cycles
            //    STA	03,s	; 5 cycles
            //    STA	A2,s	; 5 cycles
            //    LDA	A4,s	; 5 cycles
            //    AND	#$0F00	; 3 cycles
            //    ORA	#$2011	; 3 cycles
            //    STA	A4,s	; 5 cycles
            //    TSC		; 2 cycles
            //    ADC	#321	; 3 cycles
            //    TCS		; 2 cycles
            //    LDA	00,s	; 5 cycles
            //    AND	#$00F0	; 3 cycles
            //    ORA	#$1101	; 3 cycles
            //    STA	00,s	; 5 cycles
            //    LDA	03,s	; 5 cycles
            //    AND	#$0F00	; 3 cycles
            //    ORA	#$2012	; 3 cycles
            //    STA	03,s	; 5 cycles
            //    LDA	#$1211	; 3 cycles
            //    STA	02,s	; 5 cycles
            //; Total Cost = 94 cycles

            initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost);
        }
        static void Main(string[] args)
        {
            var   data      = new List <byte>();
            var   mask      = new List <byte>();
            var   filename  = (string)null;
            Color?maskColor = null;
            int?  maxCycles = null;
            var   sprite    = new List <SpriteByte>();
            bool  verbose   = false;

            var p = new FluentCommandLineParser();

            p.Setup <List <string> >('d', "data")
            .Callback(_ => data = _.Select(s => Convert.ToByte(s, 16)).ToList());

            p.Setup <List <string> >('m', "mask")
            .Callback(_ => mask = _.Select(s => Convert.ToByte(s, 16)).ToList());

            p.Setup <string>('i', "image")
            .Callback(_ => filename = _);

            p.Setup <string>('l', "limit")
            .Callback(_ => maxCycles = int.Parse(_));

            p.Setup <string>('v', "verbose")
            .Callback(_ => verbose = true);

            p.Setup <string>("bg-color")
            .Callback(_ => maskColor = Color.FromArgb(0xFF, Color.FromArgb(Convert.ToInt32(_, 16))));

            p.Parse(args);

            Console.WriteLine("Manual data has " + data.Count + " bytes");
            Console.WriteLine("Manual mask has " + mask.Count + " bytes");
            Console.WriteLine("Input filename is " + filename);
            Console.WriteLine("Image mask color is " + (maskColor.HasValue ? maskColor.ToString() : "(none)"));

            // Set the global state
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = maxCycles.HasValue ?
                          SpriteGeneratorSearchProblem.Create(maxCycles.Value) :
                          SpriteGeneratorSearchProblem.Create();

            SpriteGeneratorState initialState = null;

            // Handle the difference command line cases
            if (!String.IsNullOrEmpty(filename))
            {
                var bitmap = new Bitmap(filename);
                var record = BrutalDeluxeClassifier.Decompose(bitmap, maskColor);

                record.Data.Dump();
                Console.WriteLine();
                record.Mask.Dump();
                Console.WriteLine();
                record.Classes.Dump();

                //initialState = SpriteGeneratorState.Init(sprite);
            }
            else if (data.Count == mask.Count)
            {
                initialState = SpriteGeneratorState.Init(data, mask);
            }
            else
            {
                initialState = SpriteGeneratorState.Init(data);
            }

            //var solution = search.Search(problem, initialState);
            //WriteOutSolution(solution);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            var bgcolor = source.GetPixel(0, 0);
            var record  = BrutalDeluxeClassifier.Decompose(source, bgcolor);

            var classified = new Bitmap(source.Width, source.Height);

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < (source.Width / 2); x++)
                {
                    // A mask value of 255 (0xFF) is a tansparent pair of pixels, use the background color
                    var color = BrutalDeluxeClassifier.ToRGB(record.Classes[x, y]);
                    classified.SetPixel(2 * x, y, color);
                    classified.SetPixel(2 * x + 1, y, color);
                }
            }

            pictureBox3.Image    = Expand(classified, pictureBox3.ClientSize.Width, pictureBox3.ClientSize.Height);;
            pictureBox3.SizeMode = PictureBoxSizeMode.Zoom;


            var rb_record = BrutalDeluxeClassifier.DecomposeIntoRedBlueImageMap(source, bgcolor);

            var rb_classified = new Bitmap(source.Width, source.Height);

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < (source.Width / 2); x++)
                {
                    // A mask value of 255 (0xFF) is a tansparent pair of pixels, use the background color
                    var color = BrutalDeluxeClassifier.ToRGB(rb_record.Classes[x, y]);
                    rb_classified.SetPixel(2 * x, y, color);
                    rb_classified.SetPixel(2 * x + 1, y, color);
                }
            }

            pictureBox2.Image    = Expand(rb_classified, pictureBox2.ClientSize.Width, pictureBox2.ClientSize.Height);;
            pictureBox2.SizeMode = PictureBoxSizeMode.Zoom;

            var histogram = BrutalDeluxeClassifier.GenerateStatistics(rb_record);

            textBox1.Clear();

            textBox1.AppendText("Most Common Values\n");
            textBox1.AppendText("------------------\n");
            foreach (var stat in histogram.OrderByDescending(x => x.Value).Take(10))
            {
                textBox1.AppendText(String.Format("0x{0:X} : {1}\n", stat.Key, stat.Value));
            }

            // Initialize the search
            var maxCycles = 5 + source.Height * (3 + (source.Width / 4 * 31) - 1 + 41) - 1;

            problem      = SpriteGeneratorSearchProblem.CreateSearchProblem();
            initialState = SpriteGeneratorState.Init(rb_record.SpriteData);

            var expander = new SpriteGeneratorNodeExpander();

            strategy = new InspectableTreeSearch(expander);

            strategy.Initialize(problem, initialState);
        }