Source code

This commit is contained in:
alexiondev
2026-05-08 09:25:35 -04:00
parent 4867c1ac52
commit 037f7131c2
18 changed files with 1178 additions and 0 deletions

81
src/data/generator.py Normal file
View File

@@ -0,0 +1,81 @@
import numpy as np
import cv2
from typing import Tuple, List
# Image and Grid constants
IMG_SIZE = 128
GRID_SIZE = 16
SPOT_RADIUS = 6 # Approximate radius in pixels
# Colors (BGR)
FACE_COLOR = (180, 220, 240) # Pale cream/tan
SPOT_COLOR = (50, 50, 200) # Reddish-orange
EYE_COLOR = (0, 0, 0)
def extract_coords(pid: int, mode: str = "standard") -> List[Tuple[int, int]]:
"""Extracts four (x, y) coordinates from a 32-bit PID/EC.
Standard (Little-Endian): Byte 0 (LL), 1 (LR), 2 (UL), 3 (UR)
BDSP (Big-Endian): Byte 3 (LL), 2 (LR), 1 (UL), 0 (UR)
"""
bytes_list = [
(pid >> 0) & 0xFF, # Byte 0
(pid >> 8) & 0xFF, # Byte 1
(pid >> 16) & 0xFF, # Byte 2
(pid >> 24) & 0xFF, # Byte 3
]
if mode == "bdsp":
# BDSP reads the bytes in reverse order
ordered_bytes = [bytes_list[3], bytes_list[2], bytes_list[1], bytes_list[0]]
else:
ordered_bytes = bytes_list
coords = []
for byte in ordered_bytes:
x = byte & 0x0F
y = (byte >> 4) & 0x0F
coords.append((x, y))
return coords
def generate_spinda_face(pid: int, mode: str = "standard") -> np.ndarray:
"""Generates a procedural Spinda face with spots based on the PID."""
# Create blank canvas (white)
img = np.ones((IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8) * 255
# Draw Ears
cv2.circle(img, (IMG_SIZE // 2 - 40, IMG_SIZE // 2 - 50), 20, FACE_COLOR, -1)
cv2.circle(img, (IMG_SIZE // 2 - 40, IMG_SIZE // 2 - 50), 20, (0, 0, 0), 2)
cv2.circle(img, (IMG_SIZE // 2 + 40, IMG_SIZE // 2 - 50), 20, FACE_COLOR, -1)
cv2.circle(img, (IMG_SIZE // 2 + 40, IMG_SIZE // 2 - 50), 20, (0, 0, 0), 2)
# Draw main face (oval)
center = (IMG_SIZE // 2, IMG_SIZE // 2)
axes = (50, 60)
cv2.ellipse(img, center, axes, 0, 0, 360, FACE_COLOR, -1)
cv2.ellipse(img, center, axes, 0, 0, 360, (0, 0, 0), 2) # Outline
# Fixed Eyes
cv2.circle(img, (center[0] - 15, center[1] - 10), 4, EYE_COLOR, -1)
cv2.circle(img, (center[0] + 15, center[1] - 10), 4, EYE_COLOR, -1)
# Define Spot Zones (Relative to the 16x16 grid)
# Heuristic mapping for a more "Pokemon-like" layout
# Spot 1 (LL), Spot 2 (LR), Spot 3 (UL), Spot 4 (UR)
# These offsets are designed to place spots in their respective quadrants
quadrant_offsets = [
(center[0] - 45, center[1] + 5), # LL (Face)
(center[0] + 5, center[1] + 5), # LR (Face)
(center[0] - 45, center[1] - 55), # UL (Ear/Upper Face)
(center[0] + 5, center[1] - 55), # UR (Ear/Upper Face)
]
coords = extract_coords(pid, mode=mode)
for i, (x, y) in enumerate(coords):
offset_x, offset_y = quadrant_offsets[i]
px = int(offset_x + x * 2.5) # Scale grid to quadrant
py = int(offset_y + y * 2.5)
cv2.circle(img, (px, py), SPOT_RADIUS, SPOT_COLOR, -1)
return img