Crusader_Decomp/tools/vram_density_scan.py
2026-04-12 14:45:08 +02:00

61 lines
2.1 KiB
Python

IN_PATH = r"K:\ghidra\Crusader_Decomp\binary\Crusader - No Remorse Memdump Weapons.bin"
W,H = 1024,512
with open(IN_PATH,'rb') as f:
data = f.read()
count = min(len(data)//2, W*H)
mask = [0]*(W*H)
for i in range(count):
off = i*2
val = data[off] | (data[off+1]<<8)
if val & 0x7fff:
mask[i]=1
# row sums
row_sums = [sum(mask[y*W:(y+1)*W]) for y in range(H)]
col_sums = [sum(mask[x::W]) for x in range(W)]
# find row bands where row_sum > threshold
thr_row = max(10, int(max(row_sums)*0.05))
runs = []
inside = False
for y, s in enumerate(row_sums):
if s>thr_row and not inside:
start = y; inside=True
if s<=thr_row and inside:
end = y-1; inside=False; runs.append((start,end))
if inside: runs.append((start,H-1))
print('row runs (threshold=%d):'%thr_row, runs)
# print top runs with sums
for (s,e) in runs:
tot = sum(row_sums[s:e+1])
print('run',s,e,'rows=',e-s+1,'sum=',tot)
# find column runs similarly
thr_col = max(5, int(max(col_sums)*0.05))
cruns=[]; inside=False
for x,s in enumerate(col_sums):
if s>thr_col and not inside:
sx=x; inside=True
if s<=thr_col and inside:
ex=x-1; inside=False; cruns.append((sx,ex))
if inside: cruns.append((sx,W-1))
print('col runs (threshold=%d):'%thr_col, cruns[:10])
# Identify intersection boxes by combining top few row runs and col runs
candidates=[]
for (ry0,ry1) in runs:
for (cx0,cx1) in cruns:
# compute density
area = (ry1-ry0+1)*(cx1-cx0+1)
s = 0
for y in range(ry0,ry1+1):
s += sum(mask[y*W+cx0 : y*W+cx1+1])
if s > max(200, area*0.02):
candidates.append((cx0,ry0,cx1,ry1,s,area))
candidates.sort(key=lambda x:-x[4])
print('\nCandidates:')
for i,(x0,y0,x1,y1,s,area) in enumerate(candidates[:12]):
so = (y0*W + x0)*2
eo = ((y1*W + x1)+1)*2 -1
print(f'[{i}] box=({x0},{y0})-({x1},{y1}) area_pixels={area} nonzero={s} bytes=0x{so:06x}-0x{eo:06x}')
# print a few rows around top to locate HUD band
print('\nTop rows with nonzero counts (y:count)')
for y in range(0,160):
if row_sums[y]>0:
print(y, row_sums[y])