diff --git a/tools/isledecomp/isledecomp/compare/diff.py b/tools/isledecomp/isledecomp/compare/diff.py index 0bcf082b..3b78ecd3 100644 --- a/tools/isledecomp/isledecomp/compare/diff.py +++ b/tools/isledecomp/isledecomp/compare/diff.py @@ -2,7 +2,7 @@ from typing import Dict, List, Tuple CombinedDiffInput = List[Tuple[str, str]] -CombinedDiffOutput = Dict +CombinedDiffOutput = List[Tuple[str, List[Dict[str, Tuple[str, str]]]]] def combined_diff( @@ -24,7 +24,15 @@ def combined_diff( unified_diff = [] for group in diff.get_grouped_opcodes(context_size): - diff_chunk = [] + subgroups = [] + + # Keep track of the addresses we've seen in this diff group. + # This helps create the "@@" line. (Does this have a name?) + # Do it this way because not every line in each list will have an + # address. If our context begins or ends on a line that does not + # have one, we will have an incomplete range string. + orig_addrs = set() + recomp_addrs = set() for code, i1, i2, j1, j2 in group: if code == "equal": @@ -38,15 +46,36 @@ def combined_diff( orig_combined[i1:i2], recomp_combined[j1:j2] ) ] - diff_chunk.append({"both": both}) + + for orig_addr, _, recomp_addr in both: + if orig_addr is not None: + orig_addrs.add(orig_addr) + + if recomp_addr is not None: + recomp_addrs.add(recomp_addr) + + subgroups.append({"both": both}) else: - diff_chunk.append( + for orig_addr, _ in orig_combined[i1:i2]: + if orig_addr is not None: + orig_addrs.add(orig_addr) + + for recomp_addr, _ in recomp_combined[j1:j2]: + if recomp_addr is not None: + recomp_addrs.add(recomp_addr) + + subgroups.append( { "orig": orig_combined[i1:i2], "recomp": recomp_combined[j1:j2], } ) - unified_diff.append(diff_chunk) + orig_sorted = sorted(orig_addrs) + recomp_sorted = sorted(recomp_addrs) + + diff_slug = f"@@ -{orig_sorted[0]},{orig_sorted[-1]} +{recomp_sorted[0]},{recomp_sorted[-1]} @@" + + unified_diff.append((diff_slug, subgroups)) return unified_diff diff --git a/tools/isledecomp/isledecomp/utils.py b/tools/isledecomp/isledecomp/utils.py index 563b7ab1..a0a623a7 100644 --- a/tools/isledecomp/isledecomp/utils.py +++ b/tools/isledecomp/isledecomp/utils.py @@ -13,8 +13,18 @@ def print_combined_diff(udiff, plain: bool = False, show_both: bool = False): # Set this value for each address to try to line things up. padding_size = 0 - for group in udiff: - for subgroup in group: + for slug, subgroups in udiff: + if plain: + print("---") + print("+++") + print(slug) + else: + print(f"{colorama.Fore.RED}---") + print(f"{colorama.Fore.GREEN}+++") + print(f"{colorama.Fore.BLUE}{slug}") + print(colorama.Style.RESET_ALL, end="") + + for subgroup in subgroups: equal = subgroup.get("both") is not None if equal: diff --git a/tools/reccmp/reccmp.js b/tools/reccmp/reccmp.js index 318eb3c6..293d1906 100644 --- a/tools/reccmp/reccmp.js +++ b/tools/reccmp/reccmp.js @@ -198,7 +198,7 @@ function addrShouldAppear(addr) { const anyLineMatch = ([addr, line]) => line.toLowerCase().trim().includes(appState.query); // Flatten all diff groups for the search - const diffs = diff.flat(); + const diffs = diff.map(([slug, subgroups]) => subgroups).flat(); for (const subgroup of diffs) { const { both = [], orig = [], recomp = [] } = subgroup; @@ -416,18 +416,30 @@ class DiffDisplay extends window.HTMLElement { this.appendChild(optControl); const div = document.createElement('div'); - const obj = getDataByAddr(this.address); + const createSingleCellRow = (text, className) => { + const tr = document.createElement('tr'); + const td = document.createElement('td'); + td.setAttribute('colspan', 3); + td.textContent = text; + td.className = className; + tr.appendChild(td); + return tr; + }; + const groups = obj.diff; - groups.forEach(group => { + groups.forEach(([slug, subgroups]) => { const secondTable = document.createElement('table'); secondTable.classList.add('diffTable', 'showOrig'); const tbody = document.createElement('tbody'); secondTable.appendChild(tbody); + tbody.appendChild(createSingleCellRow('---', 'diffneg')); + tbody.appendChild(createSingleCellRow('+++', 'diffpos')); + tbody.appendChild(createSingleCellRow(slug, 'diffslug')); - const diffs = formatAsm(group, this.option); + const diffs = formatAsm(subgroups, this.option); for (const el of diffs) { tbody.appendChild(el); } diff --git a/tools/reccmp/template.html b/tools/reccmp/template.html index 84272877..2dba27fe 100644 --- a/tools/reccmp/template.html +++ b/tools/reccmp/template.html @@ -65,6 +65,10 @@ color: #80FF80; } + .diffslug { + color: #8080FF; + } + .identical { font-style: italic; text-align: center;