Files
overlay/overlay.py
2024-10-28 19:12:34 +01:00

223 lines
8.2 KiB
Python

#import irsdk
import random
import time
import tkinter as tk
from tkinter import Label, Button, Checkbutton, IntVar, Scale, Canvas, PhotoImage
class StandingsOverlay:
def __init__(self, ir):
self.ir = ir
self.root = tk.Tk()
self.setup_window()
# Overlay settings
self.show_position = IntVar(value=1)
self.show_name = IntVar(value=1)
self.show_lap = IntVar(value=0)
self.font_size = 12
self.overlay_opacity = 0.8
def setup_window(self):
# Configure main overlay window
self.root.overrideredirect(True) # No window borders
self.root.attributes("-topmost", True) # Always on top
self.root.geometry("300x400+10+10") # Adjust size and position
self.root.attributes("-alpha", self.overlay_opacity) # Transparency
# Configure standings labels
self.labels = [Label(self.root, text="", font=("Helvetica", self.font_size), bg="black", fg="white") for _ in range(10)]
for label in self.labels:
label.pack(anchor="w")
# Start data fetching loop
self.update_data()
def update_data(self):
if not self.ir.is_initialized:
self.ir.startup() # Start the SDK connection
if self.ir.is_initialized and self.ir.is_connected:
# Fetch and update standings data
drivers = self.ir['DriverInfo']['Drivers']
positions = sorted(drivers, key=lambda d: d['Position'])[:10] # Top 10 drivers
for i, driver in enumerate(positions):
display_text = ""
if self.show_position.get():
display_text += f"{driver['Position']}: "
if self.show_name.get():
display_text += f"{driver['UserName']} "
if self.show_lap.get():
display_text += f"- Lap: {driver['Lap']}"
self.labels[i].config(text=display_text)
# Refresh every 500ms
self.root.after(500, self.update_data)
def run(self):
self.root.mainloop()
class RelativeOverlay:
def __init__(self, ir):
self.ir = ir
self.root = tk.Tk()
self.setup_window()
# Overlay settings
self.font_size = 12
self.overlay_opacity = 0.8
def setup_window(self):
# Configure main overlay window
self.root.overrideredirect(True) # No window borders
self.root.attributes("-topmost", True) # Always on top
self.root.geometry("300x200+10+10") # Adjust size and position
self.root.attributes("-alpha", self.overlay_opacity) # Transparency
# Configure relative labels
self.relative_labels = [Label(self.root, text="", font=("Helvetica", self.font_size), bg="black", fg="white") for _ in range(10)]
for label in self.relative_labels:
label.pack(anchor="w")
# Start updating relative data
self.update_relative_data()
def update_relative_data(self):
if self.ir.is_initialized and self.ir.is_connected:
drivers = self.ir['DriverInfo']['Drivers']
user_index = self.ir['PlayerCarIndex']
user_driver = drivers[user_index]
user_position = user_driver['Position']
relative_positions = []
for i, driver in enumerate(drivers):
if i != user_index:
distance = driver['RelativePosition'] - user_position # Calculate relative position
lap_time_diff = driver['LapTime'] - user_driver['LapTime'] # Calculate lap time difference
relative_positions.append((driver['UserName'], distance, lap_time_diff))
# Sort by distance
relative_positions.sort(key=lambda x: abs(x[1]))
# Update relative overlay
for i, (name, distance, lap_time_diff) in enumerate(relative_positions[:10]):
display_text = f"{name}: {distance:+} - Lap Time Diff: {lap_time_diff:.2f}s"
self.relative_labels[i].config(text=display_text)
# Refresh every 500ms
self.root.after(500, self.update_relative_data)
def run(self):
self.root.mainloop()
class TrackMapOverlay:
def __init__(self, ir):
self.ir = ir
self.root = tk.Tk()
self.setup_window()
# Overlay settings
self.track_map_image = "path_to_your_track_map_image.png" # Update with the path to your track map image
self.track_map_window = None # Initialize track map overlay
def setup_window(self):
# Configure track map window
self.root.title("Track Map")
self.root.geometry("400x400")
self.canvas = Canvas(self.root, bg="white")
self.canvas.pack(fill=tk.BOTH, expand=True)
# Load and display track map image
self.track_map_image_obj = PhotoImage(file=self.track_map_image)
self.track_map_bg = self.canvas.create_image(0, 0, anchor="nw", image=self.track_map_image_obj)
# Start updating track map data
self.update_track_map()
def update_track_map(self):
if self.ir.is_initialized and self.ir.is_connected:
drivers = self.ir['DriverInfo']['Drivers']
user_index = self.ir['PlayerCarIndex']
user_driver = drivers[user_index]
user_position = user_driver['Position']
# Clear the canvas before drawing
self.canvas.delete("all")
# Load and display track map image
self.canvas.create_image(0, 0, anchor="nw", image=self.track_map_image_obj)
# Draw car positions on the track map
for driver in drivers:
x, y = self.convert_to_track_map_coordinates(driver)
self.canvas.create_oval(x - 5, y - 5, x + 5, y + 5, fill="blue") # Draw driver positions
# Refresh every 500ms
self.root.after(500, self.update_track_map)
def convert_to_track_map_coordinates(self, driver):
# Example function to convert driver coordinates to pixel positions on the track map
# Placeholder values, you need to implement actual coordinate conversion logic
track_width = 800 # Width of your track map image
track_height = 600 # Height of your track map image
# Here we would use the driver's position data to calculate the x, y coordinates on the track map
# For now, we just return placeholder values
x = track_width // 2 + (driver['Position'] - 1) * 10 # Example transformation
y = track_height // 2 - (driver['Position'] - 1) * 10 # Example transformation
return x, y
def run(self):
self.root.mainloop()
class MockIRSDK:
def __init__(self):
self.is_initialized = True
self.is_connected = True
self.drivers = self.generate_mock_drivers()
self.player_car_index = random.randint(0, len(self.drivers) - 1) # Randomly select a player car index
def generate_mock_drivers(self):
num_drivers = 20
drivers = []
for i in range(num_drivers):
drivers.append({
'UserName': f'Driver {i + 1}',
'Position': i + 1, # Simple position: 1 to num_drivers
'Lap': random.randint(1, 10), # Random lap number between 1 and 10
'LapTime': random.uniform(30, 40), # Random lap time between 30 and 40 seconds
'RelativePosition': i + 1 # For simplicity, set relative position same as position
})
return drivers
def __getitem__(self, item):
if item == 'DriverInfo':
return {'Drivers': self.drivers}
elif item == 'PlayerCarIndex':
return self.player_car_index
return None
class IRacingApplication:
def __init__(self):
self.ir = MockIRSDK()
# Create overlay instances
self.standings_overlay = StandingsOverlay(self.ir)
self.relative_overlay = RelativeOverlay(self.ir)
self.track_map_overlay = TrackMapOverlay(self.ir)
def run(self):
# Run all overlay windows
self.standings_overlay.run()
self.relative_overlay.run()
self.track_map_overlay.run()
# Run the application
app = IRacingApplication()
app.run()