So, you thought about using locally installed Microsoft Edge (chromium) or Google Chrome as automaton for your nodeJS project? Bad luck, the webdriver versions available on npm for Windows do not match the browser’s MAJOR version… That’s a FAIL! Here is how to circumvent this problem.
Retroarch provides Thumbnails for games that you have, but the list is curated and limited. MAME full non-merged has 44,000+ games and Retroarch provides only 13,000 or so. This guide will show you how to add almost all of the 44,000+ Retroarch Snapshots missing, thanks to progetto.
Retroarch can be confusing, and is not working well out-of-the-box. This guide will help you getting started fresh in minutes. It compiles all the information I wish I had when I started months ago.
Presentation of Retroarch
Retroarch is a frontend for libretro
Retroarch is NOT an emulator.
Retroarch is a cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.
Libretro is a meta-project hosting tons of emulator cores. Each core is an emulator platform. In the past, we had individual emulators for each platform, in the form of a classic app with executable, DLL, assets folders, etc. Most have been ported to libretro as a single file. On windows, they present themselves as a single DLL:
Other frontends currently maintained as of 2022 and based off Libretro (or compatible with):
A simple google trends lookup later, shows Retroarch as a clear winner:
Surprisingly, Linux solution such as OpenEmu do not seem to take off. Let’s get back to it on another thread.
Rant against Retrobat
I do not recommend Retrobat for the following reasons:
Retrobat is developed by a French oligarchy who cannot hear critiques. They assume things about you, before trying to help.
Retrobat is based on outdated dotNET 2.0 and 3.x – which is impossible to install on modern machines, without some tweaks and hacked binaries.
Retrobat does not work out of the box. It comes packaged with some Libretro cores, but don’t tell you which versions they are. I tried games that work on Retroarch with their version of FBneo, NES, SMNES, Genesis, nothing works.
Asked for help on their discord and got this: “Oh, if your machine cannot run Retroarch, forget about Retrobat”. Nice. Did I ever say I cannot run Retroarch?
As French know-it-all geniuses, these people assume things before asking and categorize you immediately. If it works for you, great. I’ll pass.
Install Retroarch portable
Download and Unpack Retroarch and Cores
The best way to maintain it, is to run it in portable mode. Get the latest stable release from here: 1.10.2 as of April 2022
Retroarch itself
The cores as well
Both will unzip under RetroArch-Win64 – keep it as it, it’s easier to maintain. Later on, you can update the installation by downloading the latest 20XX-XX-XX-RetroArch.7z package and overwriting the executable.
You can also let it download each core from within the frontend, but why bother when you have a convenient zipfile available?
Download Assets
You can but you should let Retroarch download them from the fronted. This guarantees the compatibility for the version you have.
Download BIOSpacks
It’s not necessary if your collection of Arcade games is full non-merged or merged. It does not hurt to have it either way.
Retroarch provide few BIOS packs from their assets page here, start with these
BIOS files go into Retroarch-x64\system\– unzip it under that folder.
Setup RetroArch
On the first run you will be greeted by the ozone menu:
You can change this in the Drivers screen:
glui: smartphone menu
rgui: Wii menu
xmb: Xbox menu
Setup Drivers
Setup everything exactly like that:
Video: the default video driver is vulkan but everyone fond on PSX/Wii/N64 recommend glcore
Audio: some recommend wasapi if your audio stutters or fails to play properly, it’s up to you
Setup Video
Setup everything like that:
Threaded Video: OFF – this will improve CPU demanding games at the cost of accuracy
Bilinear Filtering: ON – this is crucial for LED display, without it your games will look clean but aliased and horrible in the end
As you can see, Bilinear filtering will provide the look and feel of CRT TV on your latest 4K 70″ OLED TV.
There are tons of other filters available but this one is the fastest and bestest off the batch.
Output
Everything in there is auto-detected and depends on the video driver you already selected before (glcore or vulkan)
Fullscreen mode
You can enter Fullscreen with ALT + ENTER – no need to tweak this, it will constantly switch your dekstop when you unload games anyway
Windowed Mode
Remember Window Position and Size: ON
Scalling
Integer scale: ON – games won’t fit the entire screen but that’s fine, you likely have a 70″ TV anyway and it’s a HUGE boost in performance
Integer Scale Overscale: OFF – you don’t want your games to be cropped
Aspect Ratio: core provided – let the genius developers of the cores handle that for you
Crop Overscan: ON – don’t show garbage pixels on the edges
Synchronization
Vsync: OFF – I can’t think of any game in the past, present or future that would benefit of this. It just slows everything down
Hard GPU Sync: OFF – even worst than VSync – they did it
Sync to Exact Content Framerate: depends on your monitor/TV, and only for fullscreen non-windowed mode
Setup Audio
Since we selected xaudio, that should work with Windows just fine. leave everything default over there
Input
This is where the fun begins. This is Windows, remember. Every time you plug controllers off and on, you will lose something or something will break.
When plugin in your controllers, try to always plug the same ones in the same order on your USB hub.
After plugin in controllers, chose the port you want to setup:
Chose the one you want to be Port 1 in Device Index, and see if the controls are recognized. If not, proceed with each individual control or go ahead with Set All Controls.
Latency
You want the best experience possible:
no GPU Sync
no delay
no run-ahead
Polling behavior = whatever it does not change a thing
all the rest default
AI Service = OFF
AI Service feature allows users to play games written in a foreign language, or add text voice-overs automatically. This uses OCR (optical character recognition), machine translation, and text-to-speech. While these technologies can’t provide the same level of accuracy as curated content, it can go quite far. Machine translation can give a good gist of what’s being said, especially for some language pairs, and text-to-speech can be of great benefit for accessibility.
AI Service needs a hotkey that you press when you need it. It will send a screenshot to a url of your choice and feed you the result back, whether it’s speech or a picture overlay.
As much as you try, as much as you read their wiki, you will get nowhere until you spend a few hours and open a dozen links. It’s broken from the get go, yes. Installing it without certain parameters just won’t work. This recipe will save you hours. This recipe is just for the first master control-place.
Want to improve Photoshop Lightroom performance? Try this method! Boost your Lightroom Performance and Improve Speed! How to make Lightroom faster! Get rid of the infamous Loading spinner in LR CC! Pictures loading 5 times faster!!
People are (rightfully) freaking out about their privacy as the Senate voted the law S.J. 34 to let internet providers share your private data with advertisers. While it’s important to protect your privacy, it doesn’t mean that you need it at all times. Also, VPN is a service that is not free, but I found you the CHEAPEST DEAL AVAILABLE TODAY: therefore, let’s create a VPN in 15mn for $1/mo!
This guide will show you step by step how to do it with Virmach but this is valid for any other brand, provided you accept the price. The whole point is to use a script that does it for you, so you don’t have to spend a whole day doing it. Yes, setting up a VPN Server by hand is very complicated.
1. Get a KVM Server for $1/mo at Virmach
This is the crapiest, cheapest KVM provider I could find as of March 2020. Unfortunately they do not offer $1/mo plans anymore, because it depends on availability. I highly doubt they ever offered these plans in large quantities but you know how business work, yeah?
Select the cheapest KVM from the Virmach plans available here.
2. Create a RedHat, Debian, Ubuntu or CentOS server
Versions required for the script to work: Supported distros are Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS and Fedora
Ubuntu 18.04 or higher
Debian 9 or higher
CentOS 7 or higher
Fedora any version
The script that will create the OpenVPN server for you needs to be run on the major versions above. Among the limited options that Virmach offers you for that price, as of September 2021, choose one of these:
The versions shown above are the lowest versions compatible with the script. The rest of the setup in straightforward. Take note of the root password they give you and that’s it.
3. Initial Setup (optional)
Virmach will provide you a root access with a password. All the steps below are optional, especially if you already own an IaaS Cloud server access.
Let me know in the comments how long it actually took you. It took me much more than 15mn because I was writing the guide at the same time, but I think that 15mn altogether is a fair guess.
As of today, March 2020, Virmach let you pay $1 for a $1.25/mo plan because they “ran out” of cheap plans, but you are limited to 1 only. Also, no other location than within the USA are available, which defeats the purpose of a VPN when you live in the USA. What you really want is an access point in Europe.
This is the Ultimate MSDOS interactive dynamic menu with Powershell quirk. Vertical menu controlled by cursor keys via Powershell quirk + Horizontal carousel to select each option’s value.
@echo OFF
if "%~1" equ "vmenu_OptionSelection" goto :%~1
pushd %~dp0
setlocal enabledelayedexpansion
:top
set DEMO=
set DEBUG=
set VERBOSE=
set PAUSE=echo.
:: enable the line below to debug and pause at places of your choice
REM set PAUSE=pause
set POPUP=false
IF DEFINED DEBUG set VERBOSE=true
verify on
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set author=audioscavenger@it-cooking.com
set version=5.1.10
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Purpose
:: This batch is a compilation of all the crazy interactive menu examples
:: by Antonio Perez Ayala on https://www.dostips.com/forum/viewtopic.php?f=3&t=6936
::
:: By selecting options in the menu, obtain a list of variables install{product} and version{product}
:: {product} can be anything you like: AA, BB etc
:: Then you process these in your own routines
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Features
:: Vertical menu controlled by cursor keys via Powershell quirk
:: Horizontal carousel to select each option's value (we call it version)
:: Win10 compatible colors with colorless selector fallback for Vista/2012 - findstr trick is disabled
:: Tabbed indentation with parent and children
:: Jump over spacers and disabled options!
:: Multicolumns for selected version and highest detected version
:: Windows like children options toggle when Parent options are toggled
:: Auto attribution of version value to Menu option children without version
:: Dynamic indentation and menu resize
:: (Un)limited number of tab levels
:: CSV-like controlled options
:: Includes _PS_Resize trick to fit the content of the menu
:: Includes comments! How unusual...
:: Maximum 30 options
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: * TODO
:: 1. actually include hidden tools choice in the list because selector menu thinks nothing selected if only that
:: 1. add -r to arguments to REFRESH remoteVersionsAvailable
:: 1. evolve :arguments to getopt
:: 5.1 enhancements and bug-fixes:
:: 1. added local versions detection!
:: 2. finally a version flip-switch that's blocked at the edges
:: 5. bug fix: deselect a tabbed option would disable the next ones
:: 7. protect all [x] comparisons between quotes
:: 10. introduce export[%%i] to include or not selected products (used for menu parents)
:: 5.0 enhancements and bug-fixes:
:: 1. integrated magic vmenu from https://www.dostips.com/forum/viewtopic.php?f=3&t=6936
:: 2. added powershell winsize to resize window
:: 3. simplified labels definition, format and colors
:: 4. unset PAUSE on DEBUG, one may want DEBUG REMOTE
:: 5. auto jump disabled option with DO WHILE emulation
:: 7. enable disabled sub-options when selecting top option
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: set local folders
set rootDir=%CD%
set LOGS=%rootDir%\logs
md %LOGS% 2>NUL
set LOG=%LOGS%\%~n0.log
set EXAMPLE_LocalFolder=%rootDir%\install-product-files
:: TMP files management - RANDOM everytime because of file lock by our friend cmd.exe
set TMPFILE=%LOGS%\%~n0.%RANDOM%.tmp.txt
set TMPWARN=%LOGS%\%~n0.warning.%RANDOM%.tmp.log
set TMPERR=%LOGS%\%~n0.error.%RANDOM%.tmp.log
set remoteVersionsAvailable=%LOGS%\%~n0.remoteVersionsAvailable.txt
set versionsSelected=%LOGS%\%~n0.versionsSelected.tmp.txt
:start
IF DEFINED DEBUG echo %TIME% :start
:: when connected remotely via a LocalSystem agent, USERNAME=COMPUTERNAME$
IF [%USERNAME:~-1%]==[$] set AUTOMATED=true
IF NOT [%1]==[] (set AUTOMATED=true) ELSE (title %~n0 %version% - %COMPUTERNAME% - %USERNAME%@%USERDNSDOMAIN% %USERDOMAIN%)
IF DEFINED AUTOMATED call :arguments %*
IF %ERRORLEVEL% EQU 99 exit /b 0
call :detect_winVersion
IF NOT DEFINED AUTOMATED call :set_colors
call :prechecks
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: defaults - set your defaults here
:: include your default values here
:defaults
:: Windows Vista / 2012 and below: fallback for absence of colors
IF "%RC%"=="" (set "cursor=^>") ELSE set "cursor= "
:: width of your menu labels
set labelWidth=40
:: width of your indentations
set tabWidth=2
:: how many levels for your sub-menus?
set maxLevels=5
:: comment the line below to always export every options so the "export" column won't be used
set alwaysExportAll=alwaysExportAll
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: defaults
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: menu content
:menuContent
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: pre-selections: 1st field, chose what is pre-selected at start;
:: Each variable 'installXX' is a selector in the menu
:: No field can be NULL because for loop considers multiple separators as a single one
:: field 5 = set of versions available for each option in the nenu
:: It is good practice to set field 3 = product codes all the same length
:: field 4 = color includes a space as first char for color backward compatibility with previous versions of Windows
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: in this example, we also have submenu parents which won't be used,
:: it all depends on what you want to do after the options are passed back to main.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set "switch="
set "endHeader="
REM :: 1=b ; 2=c ; 4=d ; 3=e 4=f ; 5=g ; 6=h
REM :: labelLine format = tab ; select ; export ; product color ; versions ; label
REM set options=1;x;Tools; ;tools + Rkit ^(cannot remove^)
set options=1;x;Y;AA; %y%;3.3.0.12 3.2.4.0;AA label
set options=%options%/2; ;Y;AA1; %y%;3.5.5.3-US;AA1
set options=%options%/1; ;Y;BB; %y%;1.6.2.11 1.6.2.8;BB label
set options=%options%/1; ;Y;CC; %y%;5.1.0.67 5.1.0.52 5.1.0.49;CC label
set options=%options%/2; ;Y;CC1; %y%;5.1.2.30-US 5.1.1.1-US;CC1
set options=%options%/0; ;Y;spacer; %w%; ; This line is a spacer
set options=%options%/1; ;Y;PA; %y%;5.0.1.34;PA label
set options=%options%/2; ;Y;PA1; %w%;UFRII_v2.10 PCL6_v2.00;PA1 Submenu 1 xyz
set options=%options%/2; ;N;PA2ParentWontBeUsed; %w%; ;PA2 Submenu Parent
set options=%options%/3;x;Y;PA3; %w%;PCL6;PA3 Submenu 2-1 xyz
set options=%options%/3;x;Y;PA4; %w%;UFRII;PA4 Submenu 2-2 xyz
set options=%options%/2; ;Y;PB; %w%;1 2 3;xPB label
set options=%options%/1; ;N;SQLParentWontBeUsed; %w%;2017 2016 2014;SQL Parent menu
set options=%options%/2;x;Y;SQL1; %w%; ;SQL1
set options=%options%/2;x;Y;SQL2; %w%; ;SQL2
set options=%options%/0; ;Y;spacer; %w%; ; This line is a spacer
set options=%options%/1; ;Y;EXAMPLEsmthAndReloadMenu; %w%; ;Update available remote versions
:: calculate number of options here
REM for %%a in ("%options:/=" "%") do set /A lastOption+=1
for %%a in ("%options:/=" "%") do set /A totalOptions+=1
:: :detect_local_installs must be done before options definition and after options defaults
call :detect_local_installs %*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: menu content
IF NOT DEFINED AUTOMATED call :winsize 120 40 120 9997
REM IF NOT DEFINED DEMO call :EXAMPLE_setupSomeStuff
REM IF DEFINED AUTOMATED call :EXAMPLE_alterVersionsAvailableInMenu & goto :main
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: menu loop
:menu
:: you could alter the menu options before loading it, here:
REM call :EXAMPLE_alterVersionsAvailableInMenu
:: define tabbed indentations spaces here:
call :vmenu_setTabbedSpaces
:: menu needs to be redrawn with a goto
goto :vmenu_header
REM IF /I NOT [%choice%]==[n] goto :menu
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: menu loop
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: main program
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: main program
:: from here, no user interaction no more
:main
IF DEFINED VERBOSE echo %TIME% :main
IF DEFINED DEBUG echo call :vmenu_decodeOptions %select%
:: STEP 1: decode binary shift encoded options + setup install{product} and version{product} variables
call :vmenu_decodeOptions %select%
:: STEP 2: (optional) copyParentVersions from Parent menu items into their children
:: the EXAMPLE below will for example, copy the Parent submenu version into its children with empty version.
call :vmenu_copyParentVersions-EXAMPLE
:: EXAMPLE: (optional) menu loop after alteration
:: if installEXAMPLEsmthAndReloadMenu is chosen as an option,
:: it will call a routine that will alter the menu/versions and then reload the menu
IF "%installEXAMPLEsmthAndReloadMenu%"=="x" call :installsmthAndReloadMenu-EXAMPLE & goto :menu
:: STEP 3: (optional) visualize the options finally selected with their version
call :vmenu_listOptions %select%
:: STEP 4: (optional) validate each version
:: EXAMPLE: :select_versions routine will ask user to post-modify/validate each version selected
call :select_versions
echo menu selection is over. Call your routines here...
REM call :routine1
REM call :routine2
REM call :routine3
pause
goto :end
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: main program
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: main program
:installsmthAndReloadMenu-EXAMPLE
echo do something here to alter the menu options
goto :EOF
:arguments %*
IF DEFINED DEBUG echo %HIGH%%c% %~0 %END%%c% %* %END%
IF /I [%1]==[version] echo version=%version% & exit /b 99
call :USAGE & exit /b 99
goto :EOF
:USAGE
echo Usage: %~n0 [ help ^| version ^| whatever you like]
goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: start of magic vmenu
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:vmenu_header
cls
IF DEFINED DEBUG echo %TIME% %~0
REM echo(%nbsp%
call :your-logo-here
REM echo/
REM echo Example of Check List / Radio Button
REM echo/
echo Move selection lightbar with these cursor keys:
echo Home/End = First/Last, Up/Down = Prev/Next, or via option's first letter, Left/Right = set Version
echo selected local
echo [x] tools + Rkit ^(cannot remove^) ----------- + ----------
%endHeader%
if defined switch set "switch=/R"
call :vmenu_CheckList select="%options%" %switch%
echo/
echo/
if "%select%" equ "0" goto :vmenu_endProg
if DEFINED DEBUG echo DEBUG: Binary Options sum: %select%
:: example loop
goto :main
:vmenu_endProg
goto :EOF
:vmenu_CheckList select= "option1/option2/..." [/R]
setlocal EnableDelayedExpansion
:: vmenu subroutine activates a CheckList/RadioButton form controlled by cursor control keys
:: RadioButton is now certainly broken but I keep its original code for history purpose
:: %1 = Variable that receive the selection
:: %2 = Options list separated by slash
:: %3 = /R (switch) = Radio Button (instead of Check List)
:: Process /R switch
if /I "%~3" equ "/R" (
set "Radio=1"
set "unmark=( )" & set "mark=(o)"
) else (
set "Radio="
set "unmark=[ ]" & set "mark=[x]"
)
:: Separate options
set "options=%~2"
set "lastOption=0"
for %%a in ("%options:/=" "%") do (
set /A lastOption+=1
set labelLine=%%~a
REM :: 1=b ; 2=c ; 4=d ; 3=e 4=f ; 5=g ; 6=h
REM :: labelLine format = tab ; select ; export ; product color ; versions ; label
for /F "tokens=1-6* delims=;" %%b in ("!labelLine!") do (
set "tab[!lastOption!]=%%~b"
set "tabs[!lastOption!]=!tabSpaces[%%~b]!"
REM :: grab selected products and options: an "x" marks the bounty
set "select[!lastOption!]=[%%~c]"
set "install%%e=%%~c"
REM :: compatibility with Vista/Server 2012 and below: no colors available
set export[!lastOption!]=%%~d
REM :: compatibility with Vista/Server 2012 and below: no colors available
set color=%%~f
set labelColor[!lastOption!]=!color:~1!
REM :: versions used in the right column carousel
set "versions=%%~g"
set "versions[!lastOption!]=%%~g"
REM :: IMPORTANT: this is where we get the local detected versions found by :detect_local_installs
call set "versionsFound[!lastOption!]=%%versionsFound%%~e%%"
set numVersions=0
set firstVersion=
set move2Version[!lastOption!]=0
for %%v in (!versions!) DO (
set /A numVersions+=1
IF "!firstVersion!"=="" (
set firstVersion=done
set "version[!lastOption!]=%%v"
set move2Version[!lastOption!]=1
)
)
set numVersions[!lastOption!]=!numVersions!
REM set labelVersions[!lastOption!]=!thisLabelVersions!
REM :: add spaces after label to LEFT trim it after
set label=%%~h
REM :: calculate the label width and setup toggles
IF %%~b EQU 0 (
set "toggle[!lastOption!]=off"
) ELSE (
set "toggle[!lastOption!]=on"
REM :: auto-calculate label width based on tabbing
call set "option[!lastOption!]=%%label:~0,!labelWidth[%%~b]!%%"
)
)
REM :: Below we setup selected menu item with
REM :: the line below is real genius as it's a Unix like command expansion in a variable!
call set "moveSel[%%option[!lastOption!]:~0,1%%]=set sel=!lastOption!"
)
for /L %%j in (1,1,%totalOptions%) DO IF !tab[%%j]! EQU 1 call :vmenu_toggleColor %%j %totalOptions%
if defined Radio set "select[1]=%mark%"
:: Define powershell vmenu working variables
for %%a in ("Enter=13" "Esc=27" "Space=32" "Endd=35" "Home=36" "LeftArrow=37" "RightArrow=39" "UpArrow=38" "DownArrow=40" "LetterA=65" "LetterZ=90") do set %%a
set "letter=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
:: findstr trick - for Server 2012 and under
REM for /F %%a in ('echo prompt $H ^| cmd') do set "BS=%%a"
REM echo %BS%%BS%%BS%%BS%%BS%%BS% >_
:: Define movements for standard keys
:: Also define left/right options for versions
set "sel=1"
set "moveSel[%Home%]=set sel=1"
set "moveSel[%Endd%]=set sel=%lastOption%"
set "moveSel[%UpArrow%]=set /A sel-=^!^!(sel-1)"
set "moveSel[%DownArrow%]=set /A sel+=^!^!(sel-lastOption)"
:: Read keys via PowerShell -> Process keys in Batch
set /P "=Loading vmenu..." < NUL
PowerShell -executionPolicy bypass -Command ^
Write-Host 0; ^
$validKeys = %Endd%..%Home%+%LeftArrow%+%RightArrow%+%UpArrow%+%DownArrow%+%Space%+%Enter%+%Esc%+%LetterA%..%LetterZ%; ^
while ($key -ne %Enter% -and $key -ne %Esc%) { ^
$key = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode; ^
if ($validKeys.contains($key)) {Write-Host $key} ^
} ^
%End PowerShell% | "%~F0" vmenu_OptionSelection
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: THIS IS WHERE WE PASS SELECTED OPTIONS BACK TO :MAIN
:: %1 is actually "select" passed as 1st arg to this routine, since '=' sign counts as MSDOS separator
:: The trick below is called Passing variables from one routine to another: https://ss64.com/nt/endlocal.html
:: By attaching '&' to endlocal, we are able to SET a (group of) variables just before the localisation is ended
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
endlocal & set "%~1=%errorlevel%"
:: another way of passing more variables to the parent shell:
REM Endlocal&(
REM set "%~1=%errorlevel%"
REM set "versions=%version[1]% %version[2]% %version[3]%")
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: findstr trick
REM del _
exit /B
:vmenu_toggle sel maxSel
if defined Radio (
set "select[%Radio%]=%unmark%"
set "select[%1]=%mark%"
set "Radio=%1"
) else (
if "!select[%1]!" equ "%unmark%" (
set "select[%1]=%mark%"
) else (
set "select[%1]=%unmark%"
)
call :vmenu_toggleColor %1 %2
)
exit /B
:vmenu_toggleColor sel maxSel
REM :: below we en(dis)able sub-options based on their tab[%%j] value
set lastOne=0
set /A "nextSel=%1+1"
IF "!select[%1]!"=="%mark%" (set toggleNext=on) ELSE set toggleNext=off
for /L %%j in (%nextSel%,1,%2) DO (
REM :: stop processing if %%j < lastOne
IF NOT %%j LEQ !lastOne! (
REM :: stop processing if next tab is ==root
IF !tab[%%j]! EQU !tab[%1]! exit /b
REM :: stop processing if next tab is root==1 or ==itself
IF !tab[%%j]! LSS 2 exit /b
:: at this point, %%j tab is 100% > sel tab
set "toggle[%%j]=%toggleNext%"
set lastOne=%%j
IF "!select[%%j]!%toggleNext%"=="%unmark%on" call :vmenu_toggleColor %%j %2
)
)
exit /B
:vmenu_OptionSelection
setlocal EnableDelayedExpansion
rem Wait for PS code start signal
set /P "keyCode="
set /P "="
set "endHeader=exit /B"
:vmenu_ReDraw
:: vmenu_ReDraw draws every line after each key press
:: Clear the screen and show the list:
call :vmenu_header
REM :: anti flicker trick: doesn't work
REM echo(%nbsp%
< NUL (for /L %%i in (1,1,%lastOption%) do (
set "num= %%i"
set "labelVersion=!version[%%i]! "
set "labelversionsFound=!versionsFound[%%i]! "
IF DEFINED DEBUG (
set ddebug=!toggle[%%i]! !move2Version[%%i]!
set ddebugToggle=!toggle[%%i]! !move2Version[%%i]!
echo !ddebugToggle!>>ggg
)
if !tab[%%i]! EQU 0 (
REM :: spacer
echo.!ddebug!
) ELSE (
if "!toggle[%%i]!" equ "off" (
REM :: this line is disabled:
echo !num:~-2!!tabs[%%i]!%HIGH%%k%!select[%%i]! !option[%%i]! !labelVersion:~0,11!%END% ^| !labelversionsFound:~0,20!!ddebug!
) ELSE (
if "%%i" equ "%sel%" (
REM :: this line is active AND highlighted
REM :: findstr trick
REM set /P "=%k%!tab[%%i]!%END%!num:~-2! !select[%%i]! "
REM findstr /A:17 . "!option[%%i]!\..\_" NUL
REM :: We show horizontal carousel only if there is more than one version available;
REM :: also we want to show the direction where the other versions are
IF !numVersions[%%i]! GTR 1 (
IF !move2Version[%%i]! EQU !numVersions[%%i]! (
REM :: last version is shown
echo %cursor%!num:~-2!!tabs[%%i]!!select[%%i]!%cursor%%RC%%k%!option[%%i]!%END%^<%RB%%w%!labelVersion:~0,11!%END%]^| !labelversionsFound:~0,20!!ddebug!
) ELSE (
IF !move2Version[%%i]! EQU 1 (
REM :: first version is shown
echo %cursor%!num:~-2!!tabs[%%i]!!select[%%i]!%cursor%%RC%%k%!option[%%i]!%END%[%RB%%w%!labelVersion:~0,11!%END%^>^| !labelversionsFound:~0,20!!ddebug!
) ELSE (
REM :: middle versions are shown
echo %cursor%!num:~-2!!tabs[%%i]!!select[%%i]!%cursor%%RC%%k%!option[%%i]!%END%^<%RB%%w%!labelVersion:~0,11!%END%^>^| !labelversionsFound:~0,20!!ddebug!
)
)
) ELSE (
REM :: only one version is shown
echo %cursor%!num:~-2!!tabs[%%i]!!select[%%i]!%cursor%%RC%%k%!option[%%i]!%END%[!labelVersion:~0,11!%END%]^| !labelversionsFound:~0,20!!ddebug!
)
) else (
REM :: this line is active but not highlighted
IF "!select[%%i]!"=="%unmark%" (set versionColor=) ELSE set versionColor=%HIGH%
echo !num:~-2!!tabs[%%i]!!select[%%i]! !labelColor[%%i]!!versionColor!!option[%%i]! !labelVersion:~0,11!%END% ^| !labelversionsFound:~0,20!!ddebug!
)
)
)
)
)
echo/
set /P "=Space=(De)Select, Enter=Continue, Esc=Cancel" < NUL
REM :: Get a keycode from PowerShell
set /P "keyCode="
set /P "="
REM :: Process it: check for action keys
if %keyCode% equ %Enter% goto :vmenu_encodeSelection
if %keyCode% equ %Esc% exit 0
REM :: we process Left/Right only if numVersions > 1
IF !numVersions[%sel%]! GTR 1 (
set lastVersion=0
if %keyCode% equ %LeftArrow% (
for %%v in (!versions[%sel%]!) DO (
set /A lastVersion+=1
IF "!version[%sel%]!"=="%%v" IF !lastVersion! GTR 1 set /A "move2Version[%sel%]-=1"
)
)
if %keyCode% equ %RightArrow% (
for %%v in (!versions[%sel%]!) DO (
set /A lastVersion+=1
IF "!version[%sel%]!"=="%%v" IF !lastVersion! LSS !numVersions[%sel%]! set /A "move2Version[%sel%]+=1"
)
)
REM :: below we flip-switch the version after Left/Right is pressed
IF !lastVersion! GTR 0 (
REM :: The trick below can be used to rotate versions indefinitely back and forth:
REM IF !move2Version! GTR !lastVersion! set move2Version=1
REM IF !move2Version! LEQ 0 set move2Version=!lastVersion!
set lastVersion=0
REM :: Cannot use '!' in the tokens= part, that's too bad:
REM for /f "tokens=%move2Version[!sel!]%" %%v in ("!versions[%sel%]!") DO set "version[%sel%]=%%v" & set "versionsFound[%sel%]=%%v"
REM :: Using ! for the calculated token doesn't work, you need a full-fledge loop with increment
for %%v in (!versions[%sel%]!) DO (
set /A lastVersion+=1
IF !lastVersion! EQU !move2Version[%sel%]! set "version[%sel%]=%%v"
)
)
)
REM :: below we (un)mark options after space is pressed
if %keyCode% equ %Space% (
call :vmenu_toggle %sel% %lastOption%
goto :vmenu_ReDraw
)
REM :: Process it: check for move keys
if %keyCode% lss %LetterA% goto :vmenu_jumpSelection
REM :: Below we process pressed key from A-Z
REM :: Last Letter option wins when multiple labels start with same Letter
set /A keyCode-=LetterA
set "keyCode=!letter:~%keyCode%,1!"
:vmenu_jumpSelection
!moveSel[%keyCode%]!
REM :: jump next one if this is a spacer - first and last options cannot be a spacer
REM :: BUG: this works only for Arrows Up/Down, for Letters you actually can end on a disabled option
if "!toggle[%sel%]!"=="off" !moveSel[%keyCode%]!
REM :: jump next one if this is disabled - DO WHILE emulation
REM :: This cannot work if first or last option is disabled
:vmenu_whileDisabled
IF DEFINED DEBUG call echo toggle[%sel%]=!toggle[%sel%]! %lastOption% moveSel[%keyCode%]=!moveSel[%keyCode%]!>>ggg
REM :: the loop below will jump to next selection that's enabled when pressing a Letter,
REM :: if the letter leads to a disabled option, by forcing using an Arrow instead
if "!toggle[%sel%]!" equ "off" (
if %keyCode% GEQ %LetterA% (
if %sel% lss %lastOption% (set keyCode=38) ELSE set keyCode=40
!moveSel[%keyCode%]!
)
) ELSE goto :vmenu_whileEnd
REM keyCode 40 = up, 38 = down
if %keyCode% equ 38 (set /A "sel-=1") ELSE set /A "sel+=1"
goto :vmenu_whileDisabled
:vmenu_whileEnd
REM :loop_antiflicker
REM if "%time:~-1%"=="!time:~-1!" goto :loop_antiflicker
goto :vmenu_ReDraw
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: :vmenu_encodeSelection will create the binary encoded errorlevel used by :vmenu_decodeOptions
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:vmenu_encodeSelection
set "sel="
del /f /q %versionsSelected% >NUL 2>NUL
:: We need to process options in reverse order because that's how we'll pop then out of the errorlevel
for /L %%i in (1,1,%lastOption%) do (
REM :: we always export all versions because we process every options in reverse order
echo "!version[%%i]!">>%versionsSelected%
REM :: 1<<x = 2 power x
REM :: To get the original selections, just for loop in reverse and substract each power values of 2
REM :: We also make sure we select only those which are not disabled by checking for !toggle[%%i]!
if "!select[%%i]!!toggle[%%i]!" equ "%mark%on" (
REM :: We also export only the products tagged "Y" for export unless alwaysExportAll is set
REM :: Beware: by doing so, you do not export Parent menu items and cannot copy their version into their children in :vmenu_copyParentVersions
if /I "%alwaysExportAll%"=="alwaysExportAll" (
set /A "sel+=1<<%%i"
) ELSE (
if /I "!export[%%i]!"=="Y" (
set /A "sel+=1<<%%i"
)
)
)
)
if NOT DEFINED sel set "sel=0"
:: BUG: there is a MAX value for %sel%: ERRORLEVEL cannot be higher than 1357508192 > 2^30 = 30 options maximum
exit %sel%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:vmenu_decodeOptions %select%
IF DEFINED DEBUG echo %~0 %1 with lastOption=%lastOption%
:: %binarySum% is a binary addition: sum of all selected options as power of 2
:: BUG: there is a MAX value for binarySum: ERRORLEVEL cannot be higher than 1357508192 > 2^30 = 30 options maximum
set binarySum=%1
:: Separate options
:: TODO: this could be exported as a separate routine since we need that to reverse option selections
set "lastOption=0"
for %%a in ("%options:/=" "%") do (
REM :: 1=b ; 2=c ; 4=d ; 3=e 4=f ; 5=g ; 6=h
REM :: labelLine format = tab ; select ; export ; product color ; versions ; label
set /A lastOption+=1
set labelLine=%%~a
for /f "tokens=1-6* delims=;" %%b in ("!labelLine!") do (
set product[!lastOption!]=%%~e
)
)
:: decode each option
:: %select% is a binary addition: sum of all selected options as power of 2
for /L %%i in (%lastOption%,-1,1) do (
REM :: overwrite whatever install is detected first:
call set install!product[%%i]!=
set /A "thisOne=1<<%%i"
REM :: (sign bit -> 0) An arithmetic shift: https://ss64.com/nt/set.html
REM :: { 1 Lsh 1 = binary 01 Lsh 1 = binary 010 = decimal 2 }
REM :: { 1 Lsh 2 = binary 01 Lsh 2 = binary 0100 = decimal 4 }
REM :: { 1 Lsh 3 = binary 01 Lsh 3 = binary 01000 = decimal 8 }
REM :: etc
IF !binarySum! GEQ !thisOne! (
REM :: substract arithmetic shift from binarySum and continue
REM :: by doing so, we extract each selected option. There is a limit tho:
set /A "binarySum-=1<<%%i"
call set install!product[%%i]!=x
REM :: grab selectedVersion for product[%%i]
set line=0
for /F %%v in (%versionsSelected%) do set /A line+=1 && IF !line! EQU %%i call set "version!product[%%i]!=%%~v"
IF DEFINED DEBUG call echo DEBUG1: Now we can execute option %%i = install!product[%%i]! with version version!product[%%i]!=%%version!product[%%i]!%%
)
)
goto :EOF
:vmenu_copyParentVersions-EXAMPLE
IF DEFINED DEBUG echo %~0 %1 with lastOption=%lastOption%
:: EXAMPLE: post-process options
:: This example will attribute parent selection version to its children with empty version.
:: Don't use it if you are OK with products with empty versions
echo.
for /L %%n in (1,1,%lastOption%) do (
call set "install=%%install!product[%%n]!%%"
IF "!install!"=="x" (
call set "thisVersion=%%version!product[%%n]!%%"
IF NOT "!thisVersion!"=="" (
set lastVersion=!thisVersion!
) ELSE (
call set "version!product[%%n]!=!lastVersion!"
)
IF DEFINED DEBUG call echo DEBUG2: Now we can execute option %%n = install!product[%%n]! with version version!product[%%n]!=%%version!product[%%n]!%%
)
)
goto :EOF
:vmenu_setTabbedSpaces
for /L %%L in (1,1,%maxLevels%) DO (
for /L %%s in (1,1,%tabWidth%) DO (
set "tabSpaces=!tabSpaces! "
)
set "tabSpaces[%%L]=!tabSpaces!"
set /A "labelWidth[%%L]=labelWidth-thisTabWidth"
set /A thisTabWidth=thisTabWidth+tabWidth
)
goto :EOF
:vmenu_listOptions %select%
IF DEFINED DEBUG echo %~0 %1 with lastOption=%lastOption%
set binarySum=%1
:: %select% is a binary addition: sum of all selected options as power of 2
echo.
for /L %%i in (%lastOption%,-1,1) do (
set /A "thisOne=1<<%%i"
IF !binarySum! GEQ !thisOne! (
set /A "binarySum-=1<<%%i"
IF DEFINED DEBUG call echo DEBUG3: Now we can execute option %%i = install!product[%%i]! with version version!product[%%i]!=%%version!product[%%i]!%%
)
)
goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: end of magic menu
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:prechecks
IF DEFINED DEBUG echo %HIGH%%c% %~0 %END%%c% %* %END%
del /f /q %LOGS%\%~n0.*.tmp.* 2>NUL
for %%x in (powershell.exe) do (set powershell=%%~$PATH:x)
IF NOT DEFINED powershell call :error %~0: powershell NOT FOUND
:: test %TMP% exist and write access, i've seen cases where %TMP% is set but actually don't exist
echo]>%TMPFILE%
IF %ERRORLEVEL% NEQ 0 call :error %~0: NO writeable folder found, please logoff to reload environment... EXIT & %PAUSE% & exit
goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::: technical functions
:detect_winVersion
IF DEFINED DEBUG echo %HIGH%%c% %~0 %END%%c% %* %END%
set osType=workstation
wmic os get Caption /value | findstr Server >%TMPFILE%
IF %ERRORLEVEL% EQU 0 set osType=server
:: https://www.lifewire.com/windows-version-numbers-2625171
IF [%osType%]==[workstation] (
ver | findstr /C:"Version 10.0" && set WindowsVersion=10& goto :EOF
ver | findstr /C:"Version 6.3" && set WindowsVersion=8.1& goto :EOF
ver | findstr /C:"Version 6.2" && set WindowsVersion=8& goto :EOF
ver | findstr /C:"Version 6.1" && set WindowsVersion=7& goto :EOF
ver | findstr /C:"Version 6.0" && set WindowsVersion=Vista& goto :EOF
ver | findstr /C:"Version 5.1" && set WindowsVersion=XP& goto :EOF
) ELSE (
for /f "tokens=4" %%a in (%TMPFILE%) do set WindowsVersion=%%a
)
goto :EOF
:set_colors
set colorCompatibleVersions=-8-8.1-10-2016-2019-
IF DEFINED WindowsVersion IF "!colorCompatibleVersions:-%WindowsVersion%-=_!"=="%colorCompatibleVersions%" goto :EOF
goto :EOF
:: BUG: some space are needed after :set_colors
:your-logo-here
echo.
echo.
echo %y% __ __ __ __ ___ __ tm
echo %y% ^| \ / \ ^| ^| ^|\ ^| ^| / \ /\ ^| \ ^|__ ^|__)
echo %y% ^|__/ \__/ ^|/\^| ^| \^| ^|___ \__/ /~~\ ^|__/ ^|___ ^| \
echo %c% ,;
echo %c% `7MMpMMMb.pMMMb.
echo %c% MM MM MM
echo %c% MM MM MM
echo %c% MM MM MM
echo %c% .JMML JMML JMML
echo.%END%
goto :EOF
:error "msg"
echo.%r%
echo ==============================================================
echo %HIGH%%r% ERROR:%END%%r% %*
IF /I [%2]==[powershell] echo %y%Consider install Management Framework at https://support.microsoft.com/en-us/help/968929/ %r% 1>&2
echo ==============================================================
echo.%END%
IF NOT DEFINED AUTOMATED pause
exit
goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::: technical functions
:select_versions
IF DEFINED DEBUG echo %HIGH%%c% %~0 %END%%c% %* %END%
:: manually re-validate each version:
set choice=n
set /P choice=Would you like to manually validate each version? [%HIGH%%y%%choice%%END%]
IF /I NOT "%choice%"=="n" (
for /L %%n in (1,1,%lastOption%) do (
call set "install=%%install!product[%%n]!%%"
IF "!install!"=="x" (
call set "thisVersion=%%version!product[%%n]!%%"
set /P version!product[%%n]!=version!product[%%n]!? [%HIGH%%m%!thisVersion!%END%]
)
)
)
:: manually re-validate each product's download file:
IF %POPUP%==true (set havePOPUP=y) ELSE (set havePOPUP=n)
set /P havePOPUP=POPUP files list before download? [%HIGH%%y%%havePOPUP%%END%]
IF /I "[%havePOPUP%]"=="[y]" (set POPUP=true) ELSE (set POPUP=false)
:: EXAMPLE: post-process some product's versions to shorten them for some reason:
:: PRODUCTx short versions are used in main download section for platform.ini files: !%%ax%!
for %%P in (BB CC PA) DO call set %%Px=%%%%Pversion:~0,1%%
:: EXAMPLE: special cases for some other products:
set SQL1x=%SQL1version%
set SQL2x=%SQL1version%
set AAx=%AAversion:~0,3%
echo.
goto :EOF
:detect_local_installs %*
IF DEFINED DEBUG echo %HIGH%%c% %~0 %END%%c% %* %END%
:: detect what's present to pre-check options
:: 3 different detection patterns: your needs, your choice!
for %%P in (AA BB CC PA AA1 CC1) DO (
for /f "tokens=3 delims=-" %%v in ('dir /b install-%%P-*-product.ini 2^>NUL') DO (
CALL set install%%P=x
CALL set versionsFound%%P=%%v
)
)
for %%P in (PA1 PA2 PA3 PA4) DO (
IF EXIST %EXAMPLE_LocalFolder%\PA\%%P\ (
CALL set install%%P=x
CALL set versionsFound%%P=%%v
)
)
for %%P in (SQL1 SQL2) DO (
for /f "tokens=3 delims=-" %%v in ('dir /b install-%%P-*-platform.ini 2^>NUL') DO (
CALL set install%%P=x
CALL set versionsFound%%P=%%v
)
)
goto :EOF
:: :winsize winWidth winHeight bufWidth bufHeight
:winsize
:: Console Resize values via PowerShell (changeable)
SET "_PSResize=100 54 100 9997"
IF NOT [%4]==[] SET "_PSResize=%1 %2 %3 %4"
:: Check for powershell via PATH variable
REM POWERSHELL "Exit" >NUL 2>&1 && SET "_PS=1"
REM IF NOT DEFINED _PS (ECHO No&do something) ELSE (ECHO Yes&do something)
:: PS-Console Resizing
REM IF DEFINED _PS CALL:_PS_ReSize %_PSRESIZE%
CALL :_PS_ReSize %_PSRESIZE%
goto :EOF
:: :_PS_Resize winWidth winHeight bufWidth bufHeight
:_PS_Resize
:: Mode sets buffer size-not window size
MODE %1,%2
:: resize
powershell -executionPolicy bypass -Command "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%3;$B.height=%4;$W.buffersize=$B;}"
goto :EOF
:end
IF DEFINED DEBUG echo :end
echo %DATE% %TIME% %HIGH%%c% %~0 %END%%c% %* %END% ------- THE END
pause
del /f /q %LOGS%\%~n0.*.tmp.* 2>NUL
You checked your site SSL configuration with testssl.sh (see Test Your SSL Configuration with testssl) and it returned some SSL vulnerabilities? Here are some recipes to help you make sense of it all. You will most likely need the Mozilla SSL Configuration Generator to protect your site with an up-to-date, correct SSL configuration.
Is your current SSL Configuration secure enough? Is you https site rejecting old clients? Here comes a great tool called testssl.sh. It’s a bash script, developed by drwetter on Github, to test SSL Configurations
Enabling SSL for your site is a great idea overall. However, navigate around the multitude of SSL Configurations available for Apache and nginx is quite daunting. What’s best? What’s most secure? Are you privileging compatibility against security? testssl will help you decide what’s best for your site.
Meme Generator online are legion, and they do not offer the same options. Most will limit the size or shape of your meme, and most will apply their signature stamp on it. Plus it takes time to upload the image, refresh the page etc.
There is a solution for you though, and pretty easy believe me! It’s based on ImageMagick, with a simple drag&drop batch script for Windows. This solution will let you create classy memes even your mother would be proud of!