UltraStik 360 Programmer - Program your U360s per Rom without LedBlinky...

retango

New member
Supporter
RL Member
Hi!
I share a script I made for Rocket Launcher that programs UGC files to Ultimarc's UltraStik 360 Joysticks before launching a Rom. It uses the User Function feature of RL.
(Note: RocketLauncher can now handle UltraStick directly from RLUI. However, it requires you to enter the profile for each system / game manually. The only advantage of this script is that it allows you the define the profile for each system / rom using a .ini file)

Updated to 2.0, cmopatible with RL 1.2 (1-Jan-2017)

UltraStik 360 Programmer
You can define a different UGC file for each Rom or System. It also programs the Joysticks when you exit a Rom, allowing you to define a UGC file for the Front-end. UltraStik 360 Programmer can replace LedBlinky if you are using it only to program you U360s (as I was doing!)

UGC files (UltraStik Game Configuration) tells the UltraMap.exe program which maps to download to which joysticks (numbered 1 to 4). For example, 4-way.ugc tells UltraMap to program the 4-way Map (4-way.um, located in the Maps subfolder of the UltraMap program folder) to both joysticks 1 and 2. In this pack I include 6 UGC files: 2-way, 2-way-vertical, 4-way, 4-way-diagonal, 8-way, analog

With the UltraStick 360 Programmer, you can specify a system (MAME, Nintendo Entertainment System, Atari 2600, etc..) to use a different UGC file per Rom (a "Per Rom System"), or to use the same UGC file for all roms. I include UGC files for most MAME games in the default ini file, with the default as 8-way.

Installation
* Copy "Global.ahk" to the "Rocket Launcher\Lib\User Functions" (or "HyperLaunch\Lib\User Functions") folder. WARNING: If you have other User Functions already programmed in User Functions.ahk, do not overwrite your file. You should edit it and add the code provided here.
* Copy "UltraStik 360 Programmer.ini" to the "Rocket Launcher\Lib\User Functions"
* Edit "UltraStik 360 Programmer.ini" to specify the location of the UltraMap software (in the UltraMapExe key). If you don't have it installed, please download it from http://www.ultimarc.com/ultrastik_prog.html and install it. By default, it installs itself in C:\Program Files (x86)\UltraMap.
* Copy the provided UGC files to the UltraMap program folder (in the same folder where UltraMap.exe is in). Also copy the Maps that are in the Maps folder to your UltraMap/Maps folder. Feel free to modify these UGC files with the UltraMap software.

That's it, enjoy! You can further edit the ini file to better suit your needs:

Ini File
In the ini file (UltraStik 360 Programmer.ini, located in Rocket Launcher\Lib) you define a global default UGC (typically 8-way). This UGC is used when there is no specified UGC for either the System or the Rom.

In the [PerRomSystems] section of the ini file, enter "System Name"=true for systems that can have a different UGC files for each Rom. (e.g. MAME=true). If a system is a PerRomSystem, the script looks for a specific UGC for each Rom. If it does not find it, it looks for a default system UGC in the [Systems] section. And if it does not find it either, it uses de global default UGC.

In the [Systems] section, enter the ugc file for each system (without quotes and without the .ugc extension, e.g. Nintendo Entertainment System=8-way). If the current System is a Per Rom System, this UGC will be used as default when no rom UGC is specified. If the current system is not a Per Rom System, this UGC will be loaded for all roms of the system. If a system is not specified in this section, UltraStik 360 Programmer will use the global default.
The system "FrontEnd" is the system name assigned to the front end. This UGC is loaded each time you exit a rom.
The system "Pause" is the system name assigned Rocket Launcher's Pause. This UGC is loaded each time you enter Pause. When exiting Pause the programmer reloads the Rom's UGC.

In the [Roms] section, enter the UGC file for each rom, for all PerRomSystems (without quotes and without the .ugc extension, e.g. invaders=2-way). If a rom is not specified, the script will use the UGC given in Systems, or the global default.


Credits: I used rom UGC configs prepared by EMDB for HyperMap (http://forum.arcadecontrols.com/index.php/topic,134128.0.html), and took the main idea of this Programmer from byancey (http://forum.arcadecontrols.com/index.php/topic,143075.msg1483682.html#msg1483682). Thanks to both!

Change History
v1.01 - Works with RocketLauncher 1.01, takes advantage of the new Pause Features: StartPauseUserFeatures and StopPauseUserFeatures.

(Sorry I can't seem to be able to delete previous the uploaded file from this post!.. download v1.01!)
 

Attachments

  • UltraStik 360 Programmer.zip
    13.4 KB · Views: 34
  • UltraStik 360 Programmer 1.01.zip
    13.4 KB · Views: 57
  • UltraStik 360 Programmer 2.0.zip
    13.8 KB · Views: 130
Last edited:

retango

New member
Supporter
RL Member
@djvj, of course, please feel free to include this code directly in Rocket Launcher as an additional feature.. I am no programmer, but I tried to make it as tidy as possible, logging every step.. Again, thanks a million for RL, a truly wonderful piece of software!
 

djvj

Administrator
Staff member
Developer
Thanks and nice job retango. Glad to see user's grasping the purpose of user functions so well.

I would try it out, but my ultrastik for some reason never gets recognized in UltraMap, yet windows game controllers see it fine. Running as admin lets the driver install, but still the app never detects it. I've tried 2 different pcs and same thing. I just sent Andy an email.
 

yakk00

New member
RL Member
Thank you for this. I've been trying to "trim the fat" so THANK YOU. I have this running 2 machines, 1 horizontal and 1 vertical. Which leads me to a question for my vertical cabinet, do I need to change a setting for q-bert? I can't seem to get him to control properly. I don't have Windows rotated, I MAME setup for a vertical monitor. Thanks again!
 

retango

New member
Supporter
RL Member
@Yak00.. I'm sorry I'm not so much of an expert.. But I assume that if you do not have Windows rotated it should use the same UGC file... In any case, the way I use my U360s is via JoyToKey. I disabled Joystick support in Mame, compiled Mame with DirectInput enabled, and control Mame through the U360s via JoyToKey (the U360s end up just sending keystrokes to Mame).. Perhaps if you have Joystick support enabled in Mame there is something different, but I wouldn't be able to tell you sorry!.

@djvj thanks! Great, I hope Andy answers you soon and that and you can set up the U360s correctly, I love them.. Regards..
 

retango

New member
Supporter
RL Member
Updated to 1.01, takes advantage of new User Functions for Pause.. Define a UGC for Pause...
 

gigapig

Member
RL Member
Does this still work with the new User function? Will the ini file go in the user function folder?

At the moment I've tried adding it after ";Insert code Here" in the Global.ahk

Thank you

Code:
; Code in this file will always be run regardless of the system or game being launched
; Do not change the line with the class declaration! The class name must always be GlobalUserFunction and extend UserFunction
; This is just a sample file, you only need to implement the methods you will use the others can be deleted

class GlobalUserFunction extends UserFunction {

	; Use this function to define any code you want to run on initialization
	InitUserFeatures() {
		Global dbName
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		StartGlobalUserFeatures(){
    Log("StartGlobalUserFeatures - Starting")
    Global systemName, romName
    ProgramUltraStik360(systemName, romName)
    Log("StartGlobalUserFeatures - Ending")
}

; Use this function to define any code you may need to stop or clean up in every module on exit
StopGlobalUserFeatures(){
    Log("StopGlobalUserFeatures - Starting")
    ProgramUltraStik360("FrontEnd","Rom")
    Log("StopGlobalUserFeatures - Ending")
}

; Use this function to define any code you want to run before Pause starts
StartPauseUserFeatures(){
	Log("StartPauseUserFeatures - Starting")
	ProgramUltraStik360("Pause","Rom")
	Log("StartPauseUserFeatures - Ending")
}

; Use this function to define any code you may need to stop or clean up after Pause ends
StopPauseUserFeatures(){
	Log("StopPauseUserFeatures - Starting")
        Global systemName, romName
	ProgramUltraStik360(systemName, romName)
	Log("StopPauseUserFeatures - Ending")
}




ProgramUltraStik360(systemName, romName)
{
	;SplitPath, A_LineFile, , iniPath ;should work, but doesn't!
	iniPath :=A_ScriptDir . "\lib"

    iniFile=%iniPath%\UltraStik 360 Programmer.ini
	IfNotExist, %iniFile% 
		Log("UltraStik 360 Programmer ini file not found: " . iniFile . ". Please put the ""UltraStik 360 Programmer.ini"" file in the ""Rocket Launcher\lib"" folder.")
		
    IniRead, UltraMapExe, %iniFile%, Settings, UltraMapExe, C:\Program Files (x86)\UltraMap\UltraMap.exe
	IfNotExist, %UltraMapExe% 	
	{
		Log("UltraMap Script could not find Ultramap.exe not found: " . UltraMapExe . ". Please check path in the ini file. Exiting UltraMap Script.")
		Return
	}	
	
    SplitPath, UltraMapExe, , ugcPath
    IniRead, ugcGlobalDefault, %iniFile%, Settings, ugcGlobalDefault
	If (ugcGlobalDefault="ERROR") 
	{
		ugcGlobalDefault=8-way
		logText:=logText . "ugcGlobalDefault not found in ini file. Using 8-way as Global Default. "
	}
    
	IniRead, IsPerRom, %iniFile%, PerRomSystems, %systemName%

If (%IsPerRom%) 
{
    IniRead, ugc, %iniFile%, Roms, %romName%
	If (ugc="ERROR") 
	{
		IniRead, ugc, %iniFile%, Systems, %systemName%
		If (ugc="ERROR") 
		{
			ugc:= ugcGlobalDefault
			logText:=logText . " System is " systemName . ", a system that uses a UGC file per rom. Rom is " . romName . ". No rom nor system UGC found in the ini file, using global default: " . ugc 
		}
		Else
			logText:=logText . " System is " systemName . ", a system that uses a UGC file per rom. Rom is " . romName . ". Rom UGC not found in the ini file, using system default: " . ugc 
	}
	Else
		logText:=logText . " System is " systemName . ", a system that uses a UGC file per rom. Rom is " . romName . ". Rom UGC found in the ini file: " . ugc 
}
Else 
{    
    IniRead, ugc, %iniFile%, Systems, %systemName%
	If (ugc="ERROR") 
	{
		ugc:= ugcGlobalDefault
		logText:=logText . " System is " systemName . ", a system that uses the same UGC file for all roms. System UGC not found in ini file, using global default: " . ugc 
	}
	Else 
		logText:=logText . " System is " systemName . ", a system that uses the same UGC file for all roms. System UGC found in ini file: " . ugc 

}
 
IfNotExist, %ugcPath%\%ugc%.ugc	
{
	Log("UltraStik 360 Programmer- UGC file not found: " . ugcPath . "\" . ugc . ".ugc. Exiting UltraMap Script. " . logText)
	Return
}	
	
Run, %UltraMapExe% %ugcPath%\%ugc%.ugc /logerrors %ugcPath%\UltraMapLog.log
Log("UltraStik 360 Programmer loaded """ . ugc . ".ugc"". " . logText)
}
		RLLog.Info(A_ThisFunc . " - Ending")
	}
 

maabus

New member
RL Member
I fixed retango's script to work with the new user functions setup. I am only able to get it to work as a per rom script though.

i have this script in my lib\user Functions\Mame\ folder. it is called qbert.ahk
The rest of retango's script is installed like normal.

I can't get RL to launch the user functions for any other mode though. I dont get an error or anything.
I would like it to work for the mame emulator with all roms, but it doesnt do anything when i put it in the user functions\emulators folder and call it mame.ahk.

here is the code that is working when used as a per rom script.

Code:
; Code in this file will only be run for the game whose name matches the filename of this file and whose system name matches the folder name this file is located in
; Do not change the line with the class declaration! The class name must always be GameUserFunction and extend GameFunction
; This is just a sample file, you only need to implement the methods you will use the others can be deleted

class GameUserFunction extends GameFunction {

	; Use this function to define any code you want to run on initialization
	InitUserFeatures() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; Use this function to define any code you want to run in every module on start
	StartUserFeatures() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		Global systemName, romName
		this.ProgramUltraStik360(systemName, romName)
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; Use this function to define any code you may need to stop or clean up in every module on exit
	StopUserFeatures() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		this.ProgramUltraStik360("FrontEnd","Rom")
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; Use this function to define any code you want to run before Pause starts
	StartPauseUserFeatures() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		this.ProgramUltraStik360("Pause","Rom")
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; Use this function to define any code you may need to stop or clean up after Pause ends
	StopPauseUserFeatures() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		Global systemName, romName
		this.ProgramUltraStik360(systemName, romName)
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; These functions can be used to run custom code at certain points in each module

	; This function gets ran right before the primaryExe
	PreLaunch() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; This function gets ran right after the primaryExe
	PostLaunch() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; This function gets ran right after FadeInExit(), after the emulator is loaded
	PostLoad() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; This function gets ran after the module thread ends and before RL exits
	PostExit() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; This method gets ran right before Bezel is draw on the screen
	PreBezelDraw() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	
	; Game Specific Functions

	
	; Use this method to set fullscreen after the game is running (Used by PCLauncher only)
	; Use this function if fullscreen mode can only be set AFTER the game is running
	SetFullscreenPostLaunch(fs) {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; Use this method to set fullscreen before the game is running (Used by PCLauncher only)
	; Use this function if fullscreen mode can be set BEFORE the game is running, if fullscreen mode is set through CLI then this should return the cli switch necessary to run it windowed or fullscreen
	SetFullscreenPreLaunch(fs) {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
		Return ""
	}

	; Use this method to write any code necessary to halt the game so that Pause can be supported (Used by PCLauncher only)
	HaltGame() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}

	; Use this method to write any code necessary to restore the game so that Pause can be supported (Used by PCLauncher only)
	RestoreGame() {
		RLLog.Info(A_ThisFunc . " - Starting")
		; INSERT CODE HERE
		RLLog.Info(A_ThisFunc . " - Ending")
	}
	
	ProgramUltraStik360(systemName, romName)
	{
		;SplitPath, A_LineFile, , iniPath ;should work, but doesn't!
		iniPath :=A_ScriptDir . "\lib"

		iniFile=%iniPath%\UltraStik 360 Programmer.ini
		IfNotExist, %iniFile% 
		Log("UltraStik 360 Programmer ini file not found: " . iniFile . ". Please put the ""UltraStik 360 Programmer.ini"" file in the ""Rocket Launcher\lib"" folder.")
		
		IniRead, UltraMapExe, %iniFile%, Settings, UltraMapExe, C:\Program Files (x86)\UltraMap\UltraMap.exe
		IfNotExist, %UltraMapExe% 	
		{
			Log("UltraMap Script could not find Ultramap.exe not found: " . UltraMapExe . ". Please check path in the ini file. Exiting UltraMap Script.")
			Return
		}
		
		SplitPath, UltraMapExe, , ugcPath
		IniRead, ugcGlobalDefault, %iniFile%, Settings, ugcGlobalDefault
		If (ugcGlobalDefault="ERROR") 
		{
			ugcGlobalDefault=8-way
			logText:=logText . "ugcGlobalDefault not found in ini file. Using 8-way as Global Default. "
		}
   
		IniRead, IsPerRom, %iniFile%, PerRomSystems, %systemName%
	
		If (%IsPerRom%) 
		{
			IniRead, ugc, %iniFile%, Roms, %romName%
			If (ugc="ERROR") 
			{
				IniRead, ugc, %iniFile%, Systems, %systemName%
				If (ugc="ERROR") 
				{
					ugc:= ugcGlobalDefault
					logText:=logText . " System is " systemName . ", a system that uses a UGC file per rom. Rom is " . romName . ". No rom nor system UGC found in the ini file, using global default: " . ugc 
				}
				Else
				logText:=logText . " System is " systemName . ", a system that uses a UGC file per rom. Rom is " . romName . ". Rom UGC not found in the ini file, using system default: " . ugc 
			}
			Else
				logText:=logText . " System is " systemName . ", a system that uses a UGC file per rom. Rom is " . romName . ". Rom UGC found in the ini file: " . ugc 
		}
		Else 
		{    
			IniRead, ugc, %iniFile%, Systems, %systemName%
			If (ugc="ERROR") 
			{
				ugc:= ugcGlobalDefault
				logText:=logText . " System is " systemName . ", a system that uses the same UGC file for all roms. System UGC not found in ini file, using global default: " . ugc 
			}
			Else 
				logText:=logText . " System is " systemName . ", a system that uses the same UGC file for all roms. System UGC found in ini file: " . ugc 
		}
		IfNotExist, %ugcPath%\%ugc%.ugc	
		{
			Log("UltraStik 360 Programmer- UGC file not found: " . ugcPath . "\" . ugc . ".ugc. Exiting UltraMap Script. " . logText)
			Return
		}	
		
		Run, %UltraMapExe% %ugcPath%\%ugc%.ugc /logerrors %ugcPath%\UltraMapLog.log
		Log("UltraStik 360 Programmer loaded """ . ugc . ".ugc"". " . logText)
	}
}

if someone could explain how to make it work per emulator or system i would appreciate it.

EDIT: I got it working with per system as well.

Thank you retango for an awesome script!
 
Last edited:

retango

New member
Supporter
RL Member
Hi! Thanks a lot maabus!.. I just updated it to the new script language (attached in fist post of this thread, v2.0).. Did some testing but not very thorough.. pls tell me if there is anything that does not work...
Main changes for installation are that the script is now called Global.ahk, and that the default for the script and the ini file is un Lib/User Functions..
Regards and happy new year to all!
 

con71

New member
RL Member
Hi guys, I'm getting an error 53 from Ultramap when I try to run a game. I've installed it in the root of the C drive.
I had this working previously on a now wiped system and it was perfect. Would love to get it sorted if anyone can help.
 

gigapig

Member
RL Member

con71

New member
RL Member
Thanks @gigapig. Thanks for the response. I had followed @retango’s instructions and thought that’s all I needed.
No time to test at the moment unfortunately. I’ll post again when I get a chance.
 

con71

New member
RL Member
I managed to sort this out. It seems it was more of a permissions issue with the install folder than anything else. I’m using Win 10 Home Edition. When I installed UltraMap in the default location (Programs X86) it seems as if it didn’t have the correct rights to use the maps folder. I could get it to work but if the pc was shut down or restarted the permissions were gone again.
In the end I uninstalled it and reinstalled straight into the C drive root. So far so good. I’ll image the drive now to make sure I can revert if needed. I’ll also be turning off windows updates.
Thanks to @gigapig for his advice.
 

parabolic

New member
Hey guys, sorry to resurrect the old thread, but I cant seem to get this to work. I am running 1.2 of RL. and I have the 2.0 version of the programmer and It still wont work following the instal instructions.
I purposely moved the ultramap program to TRY and get the error. No error - so its clear its not running.
Any ideas?
Thanks!
 

maabus

New member
RL Member
If anyone is still using this I created a program that will read a Mame xml file and pull all the controller types and load it into the ultrastick 360.ini file. Currently you would need to update your ini file with any rom and controller manually. This is good for if you have clones in your mame setup, or when new systems are added to Mame.


To use you must create a Mame xml file. This can be done by going to your Mame directory, and running the following command. mame -listxml > version.xml
Load this xml file

Load your ultrastick 360.ini file located in your RocketLauncher\Lib\User Functions\UltraStik 360 Programmer.ini

Then click the update controllers button.

I have also provided the option to filter out games from being added to the list. You do not need to load this filter.

You can get a catver.ini file from Progettosnaps's site. https://www.progettosnaps.net/catver/
this will let you filter your list based on game genres. CHECK the genres you want to filter out of the list.

I have listed all of the controller types, and you can check the type of controller you want to add to the list. I have prechecked the most logical type of controller to add to Ultrastick 360.
if you do not want a controller type added just uncheck it.

Both the genre filter and controller type filter work independently of each other. If you have the genre filter loaded it will filter by genre first and then filter by controller type. If you dont load the genre filter it will just filter by controller type.

M6PdY85.png


Mame lists some games as "stick" I have converted these to "analog"
I also hard coded the qbert games and clones to be 4-way diagonal. You just need to set up a diagonal map to have the qbert games work.

I am a novice programmer, and I have tested this program many times. I believe i have everything working correctly. The only check i don't have built in yet is if you load a wrong xml file for the mame xml file. I will add this check in a later version.

Please backup your working ultrastick 360.ini file just to be safe.


I hope this helps people out! If you find any issues or have a suggestion please let me know.
 

Attachments

  • Ultrastick 360 Controler updater.zip
    9 KB · Views: 10
Last edited:
Top