It's Alive

By brakenwagen

Supporter (14)

brakenwagen's picture

30-03-2018, 03:59

It’s finally done I got everything working the way I want it too. Big thanks Manuel I couldn’t have done it without you. I would like to share with you all what I’ve put together who knows maybe somebody else has similar desires and this might save them some headache (none sense in two people losing their minds if one will do).

First I’ll show you my tcl script for locking in the Screen’s Hz so you have complete control over it.

# this script does three things
# locks in the screen refresh rate aka frequency or screen Hz
# creates a new toggle_freq called toggle_hz (the old one now no longer works) a command that switches between 50hz and 60hz
# creates a set_hz command (lets you tell the script what frequency you want as oppose to toggle) 

# 2 or 130 is 50hz
# 0 or 128 is 60hz




# stores variables
namespace eval my_suff {
	
	# stores the current user frequency setting
	variable current_hz 5
	# keeps track of weather a change in frequency was done by the software or user
	variable is_user_change 0

}
# end namespace my_suff




# this is what locks the screen refresh rate (constantly loops to check)
proc lock_hz {} {
	
	# stores the current frequency in the_freq_now
	set the_freq_now [expr {[vdpreg 9]}]
	
	#osd::display_message "Frequency is at ==${the_freq_now}==" info
		
	# checks if the frequency is at an unaccounted for rate if so leave it alone and report it
    # if the Hz is in sync with the user setting do nothing otherwise toggle the refresh rate
	if { ($the_freq_now!=2) && ($the_freq_now!=130) && ($the_freq_now!=0) && ($the_freq_now!=128) } {
				
		osd::display_message "Frequency is at an unknown number ==${the_freq_now}==" info
		puts "Frequency is at an unknown number ==${the_freq_now}=="
		# do nothing but send message
	    	
	} elseif { ($my_suff::current_hz==5) && ($the_freq_now==2 || $the_freq_now==130) } {
		
		# do nothing
		
	} elseif { ($my_suff::current_hz==6) && ($the_freq_now==0 || $the_freq_now==128) } {
		
		# do nothing
		
	} else {
		
		# this changes the frequency
		vdpreg 9    [expr {[vdpreg 9   ] ^ 2}]
		poke 0xFFE8 [expr {[peek 0xFFE8] ^ 2}]
		
		# if the user initiated the change report successful change otherwise report attempted software change 
		if {$my_suff::is_user_change==1} {
			osd::display_message "Frequency set to ==${my_suff::current_hz}0Hz==" info
			puts "Frequency set to ==${my_suff::current_hz}0Hz=="
			variable my_suff::is_user_change 0			
		} else {
			osd::display_message "Blocked software frequency change to ==${the_freq_now}==" info
			puts "Blocked software frequency change to ==${the_freq_now}=="
		}
		# end if
				
	}
	# end if
	
	# this makes lock_hz constantly loop
	after frame lock_hz	
	
}
# end proc lock_hz

# initiates lock_hz for the first time at startup
lock_hz




# allows user to switch between 50hz and 60hz (replaces toggle_freq)
# changes "is_user_change" so lock_hz knows it the user that change the Hz
proc toggle_hz {} {
	
	if {$my_suff::current_hz==5} {
	
		variable my_suff::current_hz 6
		variable my_suff::is_user_change 1
	
	} elseif {$my_suff::current_hz==6} {
	
		variable my_suff::current_hz 5
		variable my_suff::is_user_change 1
	
	}
	# end if

}
# end proc toggle_hz




# lets you tell the script what frequency you want (5 or 6) as oppose to toggle
# if no input is given it simply reports the current refresh rate to the console
proc set_hz {{arg1 null}} {
	
	# stores the current frequency in the_freq_now
	set the_freq_now [expr {[vdpreg 9]}]
	

	
	# checks if the new hz is the same as the old
	# if so change nothing and insure that the report is still sent (otherwise you get no message)
	if {$arg1==$my_suff::current_hz} {
	
		osd::display_message "Frequency set to ==${my_suff::current_hz}0Hz==" info
		puts "Frequency set to ==${my_suff::current_hz}0Hz=="
		#do nothing but send message
	
	} else {
		
		# checks what hz the user initiated and changes it to that
		# otherwise if there was no input it simply reports the current hz to the console
		if {$arg1==5} {
		
			variable my_suff::current_hz 5
			variable my_suff::is_user_change 1
		
		} elseif {$arg1==6} {
		
			variable my_suff::current_hz 6
			variable my_suff::is_user_change 1
		
		} else {
			puts "${my_suff::current_hz}0hz"
		}
		# end if
	
	}
	#end if
		
}
# end proc set_hz

Now here is my batch code. I have two bat files main 1 and main 2. There both the same expect one boots a Boosted_MSX2_EN and the other boots Panasonic_FS-A1GT because some games are picky about such things (i.e. metal gear).

@echo off

rem get user input, input directory, and convert that input directory to Unix form
set strInput=%~1
set strInputPath=%~d1%~p1
set strInputPathUnix=%strInputPath:\=/%

rem inform the user of custom scripts 
echo script to lock screen hz implemented
echo the following custom commands have been implemented
echo "toggle_hz" switch the screen hz (replaces toggle_freq)
echo "set_hz" tells the emulator what hz to use as oppose to toggle
echo if "set hz" is given no input it simply reports the current hz to console

rem instruct the user to input a joystick number and tell them the commands to assign actions to that joystick 
echo set joystick number
echo after that use these commands to assign the buttons to MSX's joystick or the emulator's commands
echo =================================================================================================================================================
echo set joystick#_config
echo bind "joy# down" command
echo dict set joystick#_config VirtualButton RealButton
echo i.e.
echo set joystick2_config "LEFT L_hat RIGHT R_hat UP U_hat DOWN D_hat A button2 B button0"
echo bind "joy2 button7 down" "toggle pause
echo dict set joystick1_config A button5
echo =================================================================================================================================================
echo active binds can be found in UserProfile\Documents\openMSX\settings.xml

rem ask the user what joystick number to use
set /p strInputJoyNum=Enter Joystick Number:

rem ask user for screen hz
set /p strScreenHz=Enter Desired Refresh Rate (5 for 50hz 6 for 60hz):

rem check what type of file was inputed and use the appropriate commands according that file type
rem if no file was given the emulator is started with no game inserted 
rem if the file is not a recognized file an error is showed and the program ends
if "%strInput%"=="" (
	echo "set renderer SDLGL-PP set power on set_hz %strScreenHz% after time 1 "unplug joyportb" after time 1 "plug joyporta joystick%strInputJoyNum%"" | "%CD%\openmsx-0.14.0-windows-vc-x64-bin\openmsx.exe" -control stdio -script "%CD%\openmsx-0.14.0-windows-vc-x64-bin\share\scripts\_hz.tcl" -machine Boosted_MSX2_EN -extb SCC+
	exit
)

if "%strInput:~-3%"=="mx1" (
	echo "set renderer SDLGL-PP set power on set_hz %strScreenHz% after time 1 "unplug joyportb" after time 1 "plug joyporta joystick%strInputJoyNum%"" | "%CD%\openmsx-0.14.0-windows-vc-x64-bin\openmsx.exe" -control stdio -script "%CD%\openmsx-0.14.0-windows-vc-x64-bin\share\scripts\_hz.tcl" -machine Boosted_MSX2_EN -carta "%strInput%" -extb SCC+
	exit
)

if "%strInput:~-3%"=="mx2" (
	echo "set renderer SDLGL-PP set power on set_hz %strScreenHz% after time 1 "unplug joyportb" after time 1 "plug joyporta joystick%strInputJoyNum%"" | "%CD%\openmsx-0.14.0-windows-vc-x64-bin\openmsx.exe" -control stdio -script "%CD%\openmsx-0.14.0-windows-vc-x64-bin\share\scripts\_hz.tcl" -machine Boosted_MSX2_EN -carta "%strInput%" -extb SCC+
	exit
)

rem an ",hdd" before the file extension indicates a hard drive image (both floppies and hard drives use the same extension ".dsk") 
if "%strInput:~-8%"==",hdd.dsk" (
	echo "set renderer SDLGL-PP set power on set_hz %strScreenHz% after time 1 "unplug joyportb" after time 1 "plug joyporta joystick%strInputJoyNum%"" | "%CD%\openmsx-0.14.0-windows-vc-x64-bin\openmsx.exe" -control stdio -script "%CD%\openmsx-0.14.0-windows-vc-x64-bin\share\scripts\_hz.tcl" -machine Boosted_MSX2_EN -extb SCC+ -exta ide -hda "%strInput%"
	exit
)

if "%strInput:~-3%" == "dsk" (
	echo "set renderer SDLGL-PP set osd_disk_path "%strInputPathUnix%" set power on set_hz %strScreenHz% after time 1 "unplug joyportb" after time 1 "plug joyporta joystick%strInputJoyNum%"" | "%CD%\openmsx-0.14.0-windows-vc-x64-bin\openmsx.exe" -control stdio -script "%CD%\openmsx-0.14.0-windows-vc-x64-bin\share\scripts\_hz.tcl" -machine Boosted_MSX2_EN -extb SCC+ -diska "%strInput%"
	exit
	
) else (
	echo not a regonized file type
	pause
	exit
)

I make a shortcut to the appropriate main in each rom folder, I even made little icons of an msx and msx A1GT to put on the shortcuts.

[img][/img]
[img][/img]

Then I bound toggle_hz to f11 and the menu to f12. After that I wanted to get rid of the led icons that was easy just use the command “load_icons none” I also wanted the menu button and messages fade quick as I didn’t not like how long they stayed on the screen.
For the menu button I opened “emulator_directory\share\scripts\osd_menu.tcl” and changed these lines
variable button_fade_timeout 0
variable button_fadeout_time 0.4
And for the on screen messages I opened “emulator_directory\share\scripts\_osd_widgets.tlc” and changed these lines
variable opaque_duration 0.6
variable fade_out_duration 0.1
variable fade_in_duration 0.1

And finally there was this weird message that would pop up in some games (i.e. Snake-It). It had something to do with possible damage to real msx hardware and since I’ve never even seen a real msx I figured I could do without it. So I opened “emulator_directory\share\scripts\callbackprocs.tcl” and deleted the warning message’s string resulting in line 50 looking like this.
message {} warning

It’s always fun to test my scripting skills and this one was a doozy, and again thank you Manuel for giving me the clues to figure this all out. (I hope i formatted this correctly)

Login or register to post comments

By JohnHassink

Ambassador (5332)

JohnHassink's picture

30-03-2018, 06:08

brakenwagen wrote:

who knows maybe somebody else has similar desires and this might save them some headache (none sense in two people losing their minds if one will do).

You're most probably the only one, but cool that you managed to do it. Must have been a fun experience. Smile

By Manuel

Ascended (14671)

Manuel's picture

30-03-2018, 22:26

Thanks for sharing your code! I played a bit with it and made this out of it, let me know what you think:

# This script does three things:
# 1. it locks in the screen refresh rate aka frequency if the setting
#    enable_fixed_frequency is on/true/yes
# 2. it creates a new toggle_freq called toggle_fixed_freq (the old one now no
#    longer works), a command that switches between 50Hz and 60Hz permanently
# 3. creates a set_fixed_freq command (lets you tell the script what frequency
#    you want as opposed to toggle) 
# TODO:
# - would it be useful to make the current fixed_freq a user setting?
#   Disadvantage is that tab completion won't work and also having no args
#   won't work.

namespace eval fixed_freq {

set_help_text toggle_fixed_freq \
{Toggles the fixed VDP frequency to the other value (50 or 60Hz).
Only effective if the enable_fixed_frequency setting is ON.
}

set_help_text set_fixed_freq \
{set_fixed_freq [50|60]
Set the VDP to a fixed display frequency of 50 or 60Hz.
Only effective if the enable_fixed_frequency setting is ON.
}

proc tabcompletion_fixed_freq {args} {
	return [ list 50 60]
}

set_tabcompletion_proc set_fixed_freq [namespace code tabcompletion_fixed_freq]

# stores the current user frequency setting
variable user_freq 50

user_setting create boolean enable_fixed_frequency "Whether to keep the VDP frequency on a fixed value, no matter what the MSX software tries to do." false

# this is what locks the screen refresh rate (constantly loops to check)
proc lock_freq {} {
	variable user_freq
	
	set current_freq [expr {[vdpreg 9] & 2} ? 50 : 60]
	
	# if the freq is in sync with the user setting do nothing otherwise
	# toggle the refresh rate
	if {$user_freq ne $current_freq} {
		toggle_freq
	}
	
	# this makes lock_freq to be called every frame
	if {$::enable_fixed_frequency} {
		after frame [namespace code lock_freq]
	}
}

proc setting_changed {name1 name2 op} {
	if {$::enable_fixed_frequency} {;# setting changed from disabled to enabled
		lock_freq
	}
}

trace add variable ::enable_fixed_frequency "write" [namespace code setting_changed]

# initiates lock_freq for the first time at startup, if enabled
setting_changed "dummy1" "dummy2" "dummy3"

# allows user to switch between 50Hz and 60Hz (replaces toggle_freq)
proc toggle_fixed_freq {} {
	variable user_freq
	if {$user_freq == 50} {
		set user_freq 60
	} elseif {$user_freq == 60} {
		set user_freq 50
	}
	return ""
}

# lets you tell the script what frequency you want (50 or 60) as opposed to
# toggle if no input is given it simply reports the current refresh rate
proc set_fixed_freq {{the_freq ""}} {
	variable user_freq
	
	# checks if the new freq is the same as the old
	# if so change nothing and insure that the report is still sent
	# (otherwise you get no message)
	if {$the_freq == $user_freq} {
		# do nothing but send message
		osd::display_message "Frequency already on ==${fixed_freq::user_freq}Hz==" info
	} else {
		# checks what freq the user initiated and changes it to that
		# otherwise if there was no input it simply reports the current
		# freq to the console
		if {($the_freq == 50) || ($the_freq == 60)} {
			set user_freq $the_freq
			return "Switching to fixed frequency of ${the_freq}Hz"
		} elseif {$the_freq eq ""} {
			return "Current fixed frequency setting is ${user_freq}Hz"
		} else {
			return "Give either 50 or 60 as argument to set your fixed frequency."
		}
	}
}

namespace export toggle_fixed_freq
namespace export set_fixed_freq

}
# end namespace fixed_freq

namespace import fixed_freq::*

By Vampier

Prophet (2226)

Vampier's picture

31-03-2018, 19:29

set_fixed_freq 50|60|Off ?

This way toggle_fixed_freq is no longer needed

By Manuel

Ascended (14671)

Manuel's picture

31-03-2018, 21:16

I didn't really look at the logic of the commands, but you have clearly a point.

I don't know why the OP kept the toggle command, I guess he wants to be able to switch easily between the 2 frequencies. Using an enum setting (50|60|off) with the 'cycle' command this could also be achieved.

So, I'll rework it a bit, will be continued....

By Manuel

Ascended (14671)

Manuel's picture

31-03-2018, 21:20

Oh, damn, user_setting doesn't support enum settings Sad

My MSX profile