Created
September 28, 2025 03:34
-
-
Save celsowm/b76222c8649e49f5e305b1e77bdb85a3 to your computer and use it in GitHub Desktop.
tga_inspector.py for Sega Saturn Jo Engine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # tga_inspect.py | |
| import sys, struct, collections | |
| IMG_TYPES = { | |
| 0: "No image data", | |
| 1: "Uncompressed, color-mapped", | |
| 2: "Uncompressed, true-color", | |
| 3: "Uncompressed, grayscale", | |
| 9: "RLE, color-mapped", | |
| 10:"RLE, true-color", | |
| 11:"RLE, grayscale", | |
| } | |
| def read_tga_header(f): | |
| hdr = f.read(18) | |
| if len(hdr) != 18: | |
| raise ValueError("Arquivo muito curto para ser TGA.") | |
| (id_len, cmap_type, img_type, | |
| cmap_first, cmap_len, cmap_entry_bits, | |
| x_origin, y_origin, width, height, | |
| pixel_depth, img_desc) = struct.unpack("<BBBHHBHHHHBB", hdr) | |
| return { | |
| "id_len": id_len, | |
| "cmap_type": cmap_type, | |
| "img_type": img_type, | |
| "cmap_first": cmap_first, | |
| "cmap_len": cmap_len, | |
| "cmap_entry_bits": cmap_entry_bits, | |
| "x_origin": x_origin, | |
| "y_origin": y_origin, | |
| "width": width, | |
| "height": height, | |
| "pixel_depth": pixel_depth, | |
| "img_desc": img_desc, | |
| "origin_top": bool(img_desc & 0x20), | |
| "origin_left": not bool(img_desc & 0x10), # 0 = left-to-right | |
| "alpha_bits": img_desc & 0x0F, | |
| } | |
| def main(path): | |
| with open(path, "rb") as f: | |
| H = read_tga_header(f) | |
| # pula ID + (eventual) paleta para checagens simples de conteúdo | |
| f.seek(18 + H["id_len"]) | |
| cmap_bytes = (H["cmap_len"] * H["cmap_entry_bits"] + 7) // 8 | |
| palette = f.read(cmap_bytes) if H["cmap_type"] == 1 else b"" | |
| print(f"Arquivo: {path}") | |
| print(f"Dimensões: {H['width']}x{H['height']}") | |
| print(f"BPP (pixel_depth): {H['pixel_depth']}") | |
| print(f"Tipo de imagem: {H['img_type']} ({IMG_TYPES.get(H['img_type'], 'desconhecido')})") | |
| print(f"ColorMap: type={H['cmap_type']} len={H['cmap_len']} first={H['cmap_first']} entry_bits={H['cmap_entry_bits']}") | |
| print(f"Origem: {'TOP' if H['origin_top'] else 'BOTTOM'}-{'LEFT' if H['origin_left'] else 'RIGHT'}") | |
| print(f"Alpha bits (desc): {H['alpha_bits']}") | |
| if palette: | |
| print(f"Paleta: {len(palette)} bytes (esperado ~ len*entry_bits/8)") | |
| # Mostra 3 primeiras entradas (assumindo 24 ou 32 bits por entrada, BGR(A)) | |
| eb = H['cmap_entry_bits'] // 8 | |
| for i in range(min(H["cmap_len"], 3)): | |
| entry = palette[i*eb:(i+1)*eb] | |
| if len(entry) == 3: | |
| b,g,r = entry | |
| print(f" pal[{i:03}]=R{r} G{g} B{b}") | |
| elif len(entry) == 4: | |
| b,g,r,a = entry | |
| print(f" pal[{i:03}]=R{r} G{g} B{b} A{a}") | |
| # Regras que interessam ao jo/VDP2 | |
| problems = [] | |
| if H["pixel_depth"] != 8: | |
| problems.append("Não é 8bpp (indexed).") | |
| if H["cmap_type"] != 1 or H["cmap_len"] == 0: | |
| problems.append("Sem paleta válida (cmap).") | |
| if H["img_type"] not in (1, 9): | |
| problems.append("Tipo não é color-mapped (1) nem RLE color-mapped (9).") | |
| if H["img_type"] == 9: | |
| problems.append("RLE habilitado — alguns loaders 8bpp não suportam.") | |
| if not H["origin_top"]: | |
| problems.append("Origem BOTTOM — experimente exportar com origem TOP (ou inverter vertical).") | |
| if H["cmap_entry_bits"] not in (24, 32): | |
| problems.append("Tamanho de entrada da paleta incomum (≠24/32 bits).") | |
| if H["width"] & (H["width"]-1) or H["height"] & (H["height"]-1): | |
| problems.append("Dimensões não potência-de-2 (pode causar problemas em planos/backgrounds).") | |
| if problems: | |
| print("\n⚠️ Possíveis problemas para o Saturn/jo:") | |
| for p in problems: print(" -", p) | |
| else: | |
| print("\n✓ Header parece compatível para VDP2 8bpp com paleta.") | |
| if __name__ == "__main__": | |
| if len(sys.argv) < 2: | |
| print("Uso: python tga_inspect.py FLR.TGA") | |
| sys.exit(1) | |
| main(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment