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])