Project pivot. Instead of q3a ra3.exe 1.80, making this work with a base quake3e engine with a console mod and the 1.76 RA3 mod.

This commit is contained in:
edschuy95 2026-01-06 21:39:09 -05:00
parent 90fd0cd571
commit 219c385558
14 changed files with 26894 additions and 17 deletions

View file

@ -6,7 +6,7 @@ import sys
import random
import re
import tkinter as tk
import psutil
#import psutil
from pathlib import Path
import queue
from tkinter import CURRENT
@ -60,7 +60,7 @@ DEFAULT_PLAYLIST = r".\arena\music\playlist.txt"
DEFAULT_RA3_MAPS = r".\arena\music\ra3_maps.txt"
# Debug override paths
DEBUG_GAME_EXE = r"D:\GOG Games\Rocket Arena 3\RA3game.dll"
DEBUG_GAME_EXE = r"D:\GOG Games\Quake III\quake3e.exe"
DEBUG_PLAYLIST = r"D:\GOG Games\Rocket Arena 3\arena\music\playlist.txt"
DEBUG_RA3_MAPS = r"D:\GOG Games\Rocket Arena 3\arena\music\ra3_maps.txt"
@ -69,6 +69,7 @@ VOLUME_STEP = 0.1 # step for W/S volume control
# ==========================================================
# ====================== GLOBAL STATE =====================
volumecheck = False
ra3_maps_path = "."
playlist = []
playlist_index = 0
@ -105,6 +106,11 @@ def console_handler(ctrl_type):
if ctrl_type == CTRL_CLOSE_EVENT:
print("\n[X] Console close requested! Signaling cleanup...")
shutdown_event.set() # Signal main thread to clean up
stop_playback()
pty_proc.close()
pygame.mixer.quit()
if WasPointerPrecisionEnabled:
set_pointer_precision(True)
return True # We've handled it
return False # Let other events pass
@ -354,6 +360,8 @@ def load_ra3_maps(path):
return maps
def next_track():
global volumecheck
volumecheck = True
send_command(pty_proc,"s_musicvolume")
global playlist_index
if current_mode == "loop":
@ -363,6 +371,8 @@ def next_track():
play_current()
def previous_track():
global volumecheck
volumecheck = True
send_command(pty_proc,"s_musicVolume")
global playlist_index
if current_mode == "loop":
@ -387,7 +397,7 @@ def play_current():
is_playing = True
current_song = Path(track).stem
print(f"[DEBUG] Playing: {current_song} at volume {volume}")
threading.Timer(.1, lambda: send_command(pty_proc,f"echo Playing: {current_song}")).start()
threading.Timer(.1, lambda: send_command(pty_proc,f"echo\r\necho\r\necho\r\necho Playing: {current_song}")).start()
except Exception as e:
print(f"[DEBUG] Couldn't start MP3 player': {e}")
#send_command(pty_proc,f"echo Playing: {Path(track).stem}")
@ -398,6 +408,8 @@ def stop_playback():
is_playing = False
def toggle_pause():
global volumecheck
volumecheck = True
send_command(pty_proc,"s_musicVolume")
global is_playing
if pygame.mixer.music.get_busy():
@ -455,15 +467,17 @@ def monitor_game(pty_proc):
def handle_game_line(line, pty_proc):
global volume, current_map, ra3_maps, ra3_maps_path
global volume, current_map, ra3_maps, ra3_maps_path, volumecheck
global serverstatus_sent, map_checked
if "--- Common Initialization Complete ---" in line:
volumecheck = True
threading.Timer(1.0, lambda: send_command(pty_proc,"s_musicVolume")).start()
if current_mode == "shuffle":
global playlist_index
playlist_index = random.randint(0, len(playlist) - 1)
threading.Timer(2.0, play_current).start()
elif line.startswith("s_musicVolume") and "\"s_musicVolume\" is:" in line:
elif line.startswith("\"s_musicVolume\"") and volumecheck == True:
volumecheck = False
svolume = parse_music_volume(line)
if svolume > 0:
if volume != svolume:
@ -515,7 +529,9 @@ def send_command_and_mark(pty_proc):
def send_command(pty_proc, cmd):
try:
pty_proc.write(("\x1bOF\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f" + cmd + "\n"))
#pty_proc.write(("\x1bOF\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f" + cmd + "\n"))
pty_proc.write(cmd + "\r\n")
#pty_proc.write((cmd + "\n").encode('utf-8'))
pty_proc.flush()
print(f"[DEBUG] Sent command: {cmd}")
except Exception as e:
@ -588,27 +604,28 @@ def main():
argsProc = sys.argv[1:]
args_lower = [arg.lower() for arg in argsProc]
args_for_game = [""]
if "--no_match_res" in args_lower:
args_for_game = ["com_skipIntroVideo", "1", "-skipmovies"] + sys.argv[1:]
else:
args_for_game = ["+set", "r_mode", "-1", "+set", "r_customWidth", f"{screenWidth}", "+set", "r_customHeight", f"{screenHeight}", "+set", "com_skipIntroVideo", "1", "-skipmovies"] + sys.argv[1:]
#args_for_game = ["com_skipIntroVideo", "1", "-skipmovies"] + sys.argv[1:]
#args_for_game = [""]
#if "--no_match_res" in args_lower:
# args_for_game = ["com_skipIntroVideo", "1", "-skipmovies"] + sys.argv[1:]
#else:
# args_for_game = ["+set", "r_mode", "-1", "+set", "r_customWidth", f"{screenWidth}", "+set", "r_customHeight", f"{screenHeight}", "+set", "com_skipIntroVideo", "1", "-skipmovies"] + sys.argv[1:]
WasPointerPrecisionEnabled=is_pointer_precision_enabled()
#WasPointerPrecisionEnabled=is_pointer_precision_enabled()
if WasPointerPrecisionEnabled:
set_pointer_precision(False)
#if WasPointerPrecisionEnabled:
# set_pointer_precision(False)
# Launch quake process via PTY
try:
pty_proc = winpty.PtyProcess.spawn([game_exe] + args_for_game)
try:
pty_proc = winpty.PtyProcess.spawn([game_exe] + sys.argv[1:] + ["+set", "fs_game", "arena", "+exec", "music_keys.cfg"])
except Exception as e:
print(f"Failed to start game via PTY: {e}")
return
game_pid = pty_proc.pid
threading.Thread(target=track_game_focus, args=(game_pid,), daemon=True).start()
#threading.Thread(target=track_game_focus, args=(game_pid,), daemon=True).start()
# Monitor the game output
try: