From af6e0224545528bd31fda371c7f1d0e1a2b73e63 Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroich Date: Thu, 23 Feb 2023 19:24:09 -0600 Subject: [PATCH] WIP for working through scanline algos --- tools/scanline-test.py | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 tools/scanline-test.py diff --git a/tools/scanline-test.py b/tools/scanline-test.py new file mode 100644 index 0000000..396e06e --- /dev/null +++ b/tools/scanline-test.py @@ -0,0 +1,105 @@ +# Playground for working through scanline decomposition algorithm + +# 1. Shadow Off +# 2. Draw Playfield (sprite OR overlay) AND NOT solid_overlay +# 3. Draw sprites + +sprites = [ + { 'top': 10, 'bottom': 17 }, + { 'top': 14, 'bottom': 29 } +] + +overlays = [ + { 'top': 0, 'bottom': 7 } +] + +MAX_HEIGHT = 199 + +# Combine a list on ranges into a minimal list by merging overlapping ranges +def simplify(a): + b = [] + if len(a) > 0: + last = a[0] + start = last['top'] + for r in a[1:]: + if r['top'] <= last['bottom']: + last = r + continue + + b.append([start, last['bottom']]) + last = r + start = r['top'] + + b.append([start, last['bottom']]) + + return b + +# Given two sorted lists, merge them together into a minimal set of ranges. This could +# be done as a list merge nd then a combine step, but we want to be more efficient and +# do the merge-and-compbine at the same time +def merge(a, b): + if len(a) == 0: + return simplify(b) + + if len(b) == 0: + return simplify(a) + + c = [] + i = j = 0 + + while i < len(a) and j < len(b): + if a[i]['top'] <= b[j]['top']: + c.append(a[i]) + i += 1 + else: + c.append(b[j]) + j += 1 + + if i < len(a): + c.extend(a[i:]) + + if j < len(b): + c.extend(b[j:]) + + return simplify(c) + +# Find the lines that need to be drawn with shadowing off +def get_shadow_off_bg(sprites): + ranges = [] + + if len(sprites) > 0: + last = sprites[0] + start = last['top'] + + for sprite in sprites[1:]: + if sprite['top'] <= last['bottom']: + last = sprite + continue + + ranges.push([start, last['bottom']]) + start = sprite['top'] + last = sprite + + ranges.append([start, last['bottom']]) + + return ranges + +def complement(ranges): + comp = [] + if len(ranges) > 0: + if ranges[0][0] > 0: + comp.append([0, ranges[0][0]]) + for i in range(1, len(ranges)): + comp.append([ranges[i-1][1]+1, ranges[i][0]]) + last = ranges[len(ranges)-1] + if last[1] < MAX_HEIGHT: + comp.append([last[1]+1, MAX_HEIGHT]) + return comp + else: + return [0, MAX_HEIGHT] + +r = get_shadow_off_bg(sprites) +print(r) +print(complement(r)) + +print(merge(sprites, overlays)) \ No newline at end of file