223 lines
8.2 KiB
Python
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()
|