diff --git a/MultiClient.py b/MultiClient.py index e4bf3a03..a18e7fc4 100644 --- a/MultiClient.py +++ b/MultiClient.py @@ -346,6 +346,17 @@ async def snes_connect(ctx : Context, address): if problem not in seen_problems: seen_problems.add(problem) logging.error(f"Error connecting to QUsb2snes ({problem})") + if len(seen_problems) == 1: + #this is the first problem. Let's try launching QUsb2snes if it isn't already running + qusb2snes_path = Utils.get_options()["general_options"]["qusb2snes"] + import os + if os.path.isfile(qusb2snes_path): + logging.info(f"Attempting to start {qusb2snes_path}") + import subprocess + subprocess.Popen(qusb2snes_path, cwd=os.path.dirname(qusb2snes_path)) + else: + logging.info(f"Attempt to start (Q)Usb2Snes was aborted as path {qusb2snes_path} was not found, please start it yourself if it is not running") + await asyncio.sleep(1) else: ctx.snes_state = SNES_CONNECTED diff --git a/host.yaml b/host.yaml index 906f43c6..90ffaaa1 100644 --- a/host.yaml +++ b/host.yaml @@ -1,6 +1,8 @@ general_options: #File name of the v1.0 J rom rom_file: "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc" + # set this to your (Q)Usb2Snes location if you want the MultiClient to attempt an auto start, does nothing if not found + qusb2snes: "QUsb2Snes\\QUsb2Snes.exe" #options for MultiServer #null means nothing, for the server this means to default the value #these overwrite command line arguments! diff --git a/icon.ico b/icon.ico new file mode 100644 index 00000000..797410ab Binary files /dev/null and b/icon.ico differ diff --git a/inno_setup.iss b/inno_setup.iss new file mode 100644 index 00000000..1cf2ae99 --- /dev/null +++ b/inno_setup.iss @@ -0,0 +1,112 @@ +#define sourcepath "build\exe.win-amd64-3.8\" +#define MyAppName "BerserkerMultiWorld" +#define MyAppExeName "BerserkerMultiClient.exe" +#define MyAppIcon "icon.ico" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +AppId={{6D826EE0-49BE-4B36-BACE-09C6971CD85C}} +AppName={#MyAppName} +AppVerName={#MyAppName} +DefaultDirName={commonappdata}\{#MyAppName} +DisableProgramGroupPage=yes +OutputDir=setups +OutputBaseFilename=Setup {#MyAppName} +Compression=lzma2 +SolidCompression=yes +LZMANumBlockThreads=8 +ArchitecturesInstallIn64BitMode=x64 +ChangesAssociations=yes +ArchitecturesAllowed=x64 +AllowNoIcons=yes +SetupIconFile={#MyAppIcon} +UninstallDisplayIcon={app}\{#MyAppExeName} +LicenseFile= LICENSE +WizardStyle= modern +SetupLogging=yes + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; + + +[Dirs] +NAME: "{app}"; Flags: setntfscompression; Permissions: everyone-modify users-modify authusers-modify; + +[Files] +Source: "{code:GetROMPath}"; DestDir: "{app}"; DestName: "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"; Flags: external +Source: "{#sourcepath}*"; Excludes: "*.key, *.log, *.hpkey"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "vc_redist.x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\{#MyAppName} Folder"; Filename: "{app}"; +Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; +Name: "{commondesktop}\{#MyAppName} Folder"; Filename: "{app}"; Tasks: desktopicon +Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/passive /norestart"; Check: IsVCRedist64BitNeeded; StatusMsg: "Installing VC++ redistributable..." +; Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + +[UninstallDelete] +Type: dirifempty; Name: "{app}" + +[Registry] + +Root: HKCR; Subkey: ".bmbp"; ValueData: "{#MyAppName}patch"; Flags: uninsdeletevalue; ValueType: string; ValueName: "" +Root: HKCR; Subkey: "{#MyAppName}patch"; ValueData: "{#MyAppName} Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: "" +Root: HKCR; Subkey: "{#MyAppName}patch\DefaultIcon"; ValueData: "{app}\{#MyAppExeName},0"; ValueType: string; ValueName: "" +Root: HKCR; Subkey: "{#MyAppName}patch\shell\open\command"; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; ValueType: string; ValueName: "" + + + +[Code] +// See: https://stackoverflow.com/a/51614652/2287576 +function IsVCRedist64BitNeeded(): boolean; +var + strVersion: string; +begin + if (RegQueryStringValue(HKEY_LOCAL_MACHINE, + 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Version', strVersion)) then + begin + // Is the installed version at least 14.24 ? + Log('VC Redist x64 Version : found ' + strVersion); + Result := (CompareStr(strVersion, 'v14.24.28127.4') < 0); + end + else + begin + // Not even an old version installed + Log('VC Redist x64 is not already installed'); + Result := True; + end; +end; + +var + ROMFilePage: TInputFileWizardPage; + +procedure InitializeWizard(); +begin + ROMFilePage := + CreateInputFilePage( + wpLicense, + 'Select ROM File', + 'Where is your Zelda no Densetsu - Kamigami no Triforce (Japan).sfc located?', + 'Select the file, then click Next.'); + + ROMFilePage.Add( + 'Location of ROM file:', + 'SNES ROM files|*.sfc|All files|*.*', + '.sfc'); +end; + +function GetROMPath(Param: string): string; +begin + if Assigned(RomFilePage) then + Result := ROMFilePage.Values[0] + else + Result := ''; + end; diff --git a/setup.py b/setup.py index 05495896..7ead2143 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,6 @@ import shutil import sys import sysconfig from pathlib import Path - import cx_Freeze is_64bits = sys.maxsize > 2 ** 32 @@ -15,9 +14,8 @@ sbuildfolder = str(buildfolder) libfolder = Path(buildfolder, "lib") library = Path(libfolder, "library.zip") print("Outputting to: " + str(buildfolder)) -build_resources = "exe_resources" compress = False -holoviews = False +icon="icon.ico" from hashlib import sha3_512 import base64 @@ -54,7 +52,8 @@ exes = [] for script, scriptname in scripts.items(): exes.append(cx_Freeze.Executable( script=script, - targetName=scriptname + ("" if sys.platform == "linux" else ".exe")) + targetName=scriptname + ("" if sys.platform == "linux" else ".exe"), + icon=icon) ) @@ -63,9 +62,9 @@ import datetime buildtime = datetime.datetime.now() cx_Freeze.setup( - name="HonorarPlus", + name="BerserkerMultiWorld", version=f"{buildtime.year}.{buildtime.month}.{buildtime.day}.{buildtime.hour}", - description="HonorarPlus", + description="BerserkerMultiWorld", executables=exes, options={ "build_exe": {