ScrollViewport.java

1
package com.rox.ppu.debug;
2
3
/**
4
 * Computes the 1-4 rectangle segments a fixed-size viewport box splits into when its origin plus size
5
 * overflows a periodic canvas. The NES nametable grid wraps at its edges - scrolling past the
6
 * right/bottom seam continues seamlessly back at x=0/y=0 - so a viewport straddling that seam is
7
 * genuinely two (or, at a corner, four) separate on-screen regions, not one contiguous rectangle.
8
 *
9
 * Assumes {@code boxWidth <= canvasWidth} and {@code boxHeight <= canvasHeight} (true for a 256x240
10
 * viewport over a 256/512-wide, 240/480-tall nametable grid), so each axis wraps at most once.
11
 */
12
final class ScrollViewport {
13
    private ScrollViewport(){
14
    }
15
16
    /**
17
     * @return between 1 and 4 {@code [x, y, width, height]} rectangles, in canvas coordinates, whose
18
     *         union is the box wrapped onto a {@code canvasWidth x canvasHeight} periodic canvas.
19
     */
20
    static int[][] segments(final int originX, final int originY, final int boxWidth, final int boxHeight,
21
                             final int canvasWidth, final int canvasHeight){
22
        final int[][] xSpans = axisSpans(Math.floorMod(originX, canvasWidth), boxWidth, canvasWidth);
23
        final int[][] ySpans = axisSpans(Math.floorMod(originY, canvasHeight), boxHeight, canvasHeight);
24
25 1 1. segments : Replaced integer multiplication with division → KILLED
        final int[][] segments = new int[xSpans.length * ySpans.length][4];
26
        int i = 0;
27
        for (final int[] xSpan : xSpans){
28
            for (final int[] ySpan : ySpans){
29 1 1. segments : Changed increment from 1 to -1 → KILLED
                segments[i++] = new int[]{xSpan[0], ySpan[0], xSpan[1], ySpan[1]};
30
            }
31
        }
32 1 1. segments : replaced return value with null for com/rox/ppu/debug/ScrollViewport::segments → KILLED
        return segments;
33
    }
34
35
    /** @return {@code [[start, length]]}, or {@code [[start, firstLength], [0, remainder]]} if it wraps. */
36
    private static int[][] axisSpans(final int start, final int length, final int canvasLength){
37 1 1. axisSpans : Replaced integer subtraction with addition → KILLED
        final int firstLength = Math.min(length, canvasLength - start);
38 2 1. axisSpans : changed conditional boundary → KILLED
2. axisSpans : negated conditional → KILLED
        if (firstLength >= length){
39 1 1. axisSpans : replaced return value with null for com/rox/ppu/debug/ScrollViewport::axisSpans → KILLED
            return new int[][]{{start, length}};
40
        }
41 2 1. axisSpans : Replaced integer subtraction with addition → KILLED
2. axisSpans : replaced return value with null for com/rox/ppu/debug/ScrollViewport::axisSpans → KILLED
        return new int[][]{{start, firstLength}, {0, length - firstLength}};
42
    }
43
}

Mutations

25

1.1
Location : segments
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:overflowingBothAxesSplitsIntoFourSegments()]
Replaced integer multiplication with division → KILLED

29

1.1
Location : segments
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:overflowingBothAxesSplitsIntoFourSegments()]
Changed increment from 1 to -1 → KILLED

32

1.1
Location : segments
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:overflowingBothAxesSplitsIntoFourSegments()]
replaced return value with null for com/rox/ppu/debug/ScrollViewport::segments → KILLED

37

1.1
Location : axisSpans
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:overflowingBothAxesSplitsIntoFourSegments()]
Replaced integer subtraction with addition → KILLED

38

1.1
Location : axisSpans
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:singleScreenSizedCanvasWithZeroOriginFillsWholeCanvas()]
changed conditional boundary → KILLED

2.2
Location : axisSpans
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:overflowingBothAxesSplitsIntoFourSegments()]
negated conditional → KILLED

39

1.1
Location : axisSpans
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:singleScreenSizedCanvasWithZeroOriginFillsWholeCanvas()]
replaced return value with null for com/rox/ppu/debug/ScrollViewport::axisSpans → KILLED

41

1.1
Location : axisSpans
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:overflowingBothAxesSplitsIntoFourSegments()]
Replaced integer subtraction with addition → KILLED

2.2
Location : axisSpans
Killed by : com.rox.ppu.debug.ScrollViewportTest.[engine:junit-jupiter]/[class:com.rox.ppu.debug.ScrollViewportTest]/[method:overflowingBothAxesSplitsIntoFourSegments()]
replaced return value with null for com/rox/ppu/debug/ScrollViewport::axisSpans → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1