Hard Light Productions Forums
Modding, Mission Design, and Coding => The Modding Workshop => Topic started by: burstdragon323 on May 18, 2016, 07:04:17 pm
-
So, I applied the Scripted Mouse from the wiki, and since I don't have the "mouse_ret_2.dds" file, I get a very hard to see X as my steering guide.
I know Wing Commander Saga has an icon, but my bad internet takes forever to download the game.
Could someone provide the file for me?
Please and thanks in advance!
-
Does the link in my signature for Mouse as Joystick have that file (or another workaround) included? EDIT: link (http://www.hard-light.net/forums/index.php?topic=74435.0)
Quoted below for convenience:
I figure this probably needs it's own topic.
This is a slightly modified version of the mouse script found here:
http://www.hard-light.net/wiki/index.php/Script_-_Scripted_Mouse
The main difference is that the middle mouse button, instead of recentering the mouse, toggles the "joystick-like" mode the mouse script provides on and off. You can quickly switch between "normal" mouse control and "Freelancer-like" mouse control, which can be handy at times.
The other change is that the "Boundary Limit" configuration attribute was removed, since it was basically redundant. The limit for mouse motion is now more simply defined by the sensitivity setting.
Installing this is the same as installing the normal scripted mouse (see link above). Just use the code below in the file instead of the normal mouse script.
Things it would be nice to improve:
- Transition between mouse modes can be a bit jarring. Smoothing this out would be a nice addition (my stab at it has so far failed)
- It would be nice to have more options for how to toggle than middle mouse button (such as using the keyboard)
data/tables/mouse-sct.tbm
#Conditional Hooks
$Application: FS2_Open
$On Mission Start:
[
--NEW PARSER
----------------------
-- parser functions --
----------------------
--- get newline and make sure its lowercase
function get_next_line(nfile)
-- read the line
nline = nfile:read("*l")
-- change to lowercase
if nline ~= nil then
nline = nline:lower()
end
return nline
end
--- find keyword and return the place where it ends
function find_keyword(line_to_parse, keyword)
-- find any instances of the keyword
keyword = keyword:lower()
local key_s, key_e = line_to_parse:find(keyword)
-- if we cant find a thing
if key_s == nil then
return nil
end
-- check if the line has been commented away
local comment_s, comment_e = line_to_parse:find("--")
if comment_s == nil then
return key_e
elseif comment_s < key_s then
return nil
end
return key_e
end
--- specific parsing funcs to make things easier to read ---
--- string or rather substring parser
function parse_string(start_key, line_to_parse)
local substring = line_to_parse:sub(start_key)
-- remove empty spaces
local substring_start = substring:find("%a")
substring = substring:sub(substring_start)
return substring
end
--- function to parse numbers
function parse_number(start_key, line_to_parse)
local result = line_to_parse:sub(start_key)
local r_value = result:match('[0-9%.]+')
r_value = tonumber(r_value)
return r_value
end
--- function to parse arrays of numbers
function parse_number_array(start_key, line_to_parse)
-- stuff the array
local r = { }
local p
for p in line_to_parse:gmatch('[0-9%.]+') do
p = tonumber(p)
p = math.floor(p)
table.insert(r, p)
end
return r
end
--- function to parse things
function parse_entry(keyword, mousefile, type, use_same_line)
local new_entry = nil
local return_val
local return_array = {}
local c_line
if use_same_line == false then
c_line = get_next_line(mousefile)
if c_line == nil then
-- end of file
return -2, false, return_array
end
while c_line:len() == 0 do
c_line = get_next_line(mousefile)
if c_line == nil then
-- end of file
return -2, false, return_array
end
end
current_start_line = c_line
else
c_line = use_same_line
end
local c_key = nil
while c_key == nil do
-- we didn't find the thing...
c_key = find_keyword(c_line, keyword)
if c_key == nil then
local comment_s = nil
comment_s = c_line:find("//")
if comment_s ~= nil then
c_line = get_next_line(mousefile)
if c_line == nil then
-- end of file
return -2, false, return_array
end
while c_line:len() == 0 do
c_line = get_next_line(mousefile)
if c_line == nil then
return -2, false, return_array
end
end
else
-- try next entry
return -1, c_line, return_array
end
end
end
if type == "n" then
-- soo... parse a number
return_array[1] = parse_number(c_key, c_line)
return_val = #return_array
return return_val, false, return_array
elseif type == "array_n" then
-- soo... parse an array of numbers
return_array = parse_number_array(c_key, c_line)
return_val = #return_array
return return_val, false, return_array
end
return -1, c_line, return_array
end
function cap_value(min_val, max_val, value)
if min_val > value then
value = min_val
elseif max_val < value then
value = max_val
end
return value
end
-- actual parsing function
function parse_mousefile(mousefile)
use_same_line = false
local current_start_line = use_same_line
local not_new_entry = false
local entry_start = 1
local still_parsing = true
while still_parsing == true do
if use_same_line == false then
use_same_line = get_next_line(mousefile)
end
if use_same_line == nil then
-- end of file
still_parsing = false
break
end
if use_same_line:len() == 0 then
use_same_line = false
else
current_start_line = use_same_line
if entry_start ~= nil then
while entry_start ~= nil do
if not_new_entry == false then
ba.print("\nScripted Mouse Loading\n")
end
local temp_val = nil
local temp_arr = nil
entry_start = nil
temp_val, use_same_line, temp_arr = parse_entry("Sensitivity:", mousefile, "n", use_same_line)
if temp_val == -2 then
break
elseif temp_val ~= -1 then
temp_arr[1] = cap_value(100, 600, temp_arr[1])
ba.print("\tSensitivity: " .. temp_arr[1] .. "\n")
mousesensitivity = temp_arr[1]
end
temp_val, use_same_line, temp_arr = parse_entry("Sensitivity Curve:", mousefile, "n", use_same_line)
if temp_val == -2 then
break
elseif temp_val ~= -1 then
temp_arr[1] = cap_value(0, 6, temp_arr[1])
ba.print("\tSensitivity Curve: " .. temp_arr[1] .. "\n")
mousesensitivitymode = temp_arr[1]
end
temp_val, use_same_line, temp_arr = parse_entry("Control Mode:", mousefile, "n", use_same_line)
if temp_val == -2 then
break
elseif temp_val ~= -1 then
ba.print("\tControl Mode: " .. temp_arr[1] .. "\n")
mousecontrolmode = temp_arr[1]
end
temp_val, use_same_line, temp_arr = parse_entry("Deadzone:", mousefile, "n", use_same_line)
if temp_val == -2 then
break
elseif temp_val ~= -1 then
temp_arr[1] = cap_value(0, 300, temp_arr[1])
ba.print("\tDeadzone: " .. temp_arr[1] .. "\n")
mousedeadzone = temp_arr[1]
end
temp_val, use_same_line, temp_arr = parse_entry("Mouse Invert:", mousefile, "n", use_same_line)
if temp_val == -2 then
break
elseif temp_val ~= -1 then
if temp_arr[1] ~= 0 then
temp_arr[1] = 1
end
ba.print("\tMouse Invert: " .. temp_arr[1] .. "\n")
mouseinvert = temp_arr[1]
end
temp_val, use_same_line, temp_arr = parse_entry("Indicator Color:", mousefile, "array_n", use_same_line)
if temp_val == -2 then
break
elseif temp_val ~= -1 then
ba.print("\tIndicator Color: " .. temp_val .. "\n")
mousecolors = temp_arr
end
if use_same_line ~= false then
ba.warning("Bogus string in mouse config file: " .. use_same_line)
end
end
else
use_same_line = false
end
end
end
end
--NEW PARSER
function verify_mouse_data()
-- make sure we have a number in deadzone var and not nil
if mousedeadzone == nil then
mousedeadzone = 0
end
-- define some variables
mouse_reset_counter = nil
missiontime_old = 0
missiontime = nil
-- if mouse invert was set to true, then invert the mouse (set it to '-1')
-- otherwise define the multiplier as '1'
if mouseinvert == 1 then
mouseinvert = -1
else
mouseinvert = 1
end
-- check that defined control area is not larger than the actual area which can be controlled
local max_limits
max_limits = mousesensitivity * 2 + mousedeadzone * 2 + 10
scr_width = gr.getScreenWidth()
scr_height = gr.getScreenHeight()
mouse_center_x = scr_width / 2
mouse_center_y = scr_height / 2
if max_limits > scr_width or max_limits > scr_height then
ba.warning("Mouse control area defined to be larger than the window size, please resize")
end
--setup mouse bitmap
mouse_bm = gr.loadTexture("mouse_ret_2.dds", true)
if mouse_bm:isValid() then
no_bitmap = false
mouse_bm_w = mouse_bm:getWidth() / 2
mouse_bm_h = mouse_bm:getHeight() / 2
else
no_bitmap = true
end
end
-----------------------------------------------------------------------
-- check if the file containing mouse references exists
-----------------------------------------------------------------------
filename_mouse = "mouse_script.cfg"
boolmousefileOK = cf.fileExists(filename_mouse, "data/config/", true)
boolscriptmouse = false
togglescriptmouse = false
old_h = 0
old_p = 0
-- if file exists
if boolmousefileOK then
-- reset all the variables to nil
mousesensitivity = nil
mousesensitivitymode = nil
mousecontrolmode = nil
mousedeadzone = nil
mouseinvert = nil
mousecolor = nil
mousecolors = {}
-- open the file in read only mode
mousefile = cf.openFile(filename_mouse, "r")
-- do the parsing thing
parse_mousefile(mousefile)
-- all data read.. time to close the file
mousefile:close()
-- if these three were found from the cfg file...
if mousesensitivity and mousesensitivitymode and mousecontrolmode then
-- set script to actually run, allow lua to override c coded controls
boolscriptmouse = true
ba.setControlMode(LUA_FULL_CONTROLS)
verify_mouse_data()
else
ba.warning("Scripted mouse's init failed")
end
else
ba.warning("File '" .. filename_mouse .."' not found")
end
------------------------
------ functions -------
------------------------
function mouse_control_A(value, centervalue, axis)
-- get the actual difference from centerpoint
delta = value - centervalue
-- default multiplier to +1
multiplier = 1
-- if we are handling negative values set multiplier to -1
-- and make sure we deal only with positive values
if delta < 0 then
multiplier = -1
delta = math.abs(delta)
end
-- deduct deadzone from the delta
delta = delta - mousedeadzone
if delta < 0 then
delta = 0
end
-- scale delta from 0 to 1 according to defined sensitivity
delta = delta / mousesensitivity
if delta > 1 then
delta = 1
end
-- if we do not have extreme values
-- apply the defined sensitivity curve
if (delta > 0) and (delta < 1) then
delta = math.pow(delta, mousesensitivitymode)
end
-- apply the multiplier
delta = delta * multiplier
return delta
end
------------------------
function do_boundaries_check(sensitivity, center_x, center_y)
f_mouse_x = nil
f_mouse_y = nil
-- Do we go outside sensitivity zone
f_mouse_x = cap_value(center_x - sensitivity, center_x + sensitivity, mouse_x)
f_mouse_y = cap_value(center_y - sensitivity, center_y + sensitivity, mouse_y)
-- reset the cursor to the nearest boundary
if f_mouse_x ~= nil or f_mouse_y ~= nil then
if f_mouse_x and f_mouse_y then
io.forceMousePosition(f_mouse_x, f_mouse_y)
elseif f_mouse_x then
io.forceMousePosition(f_mouse_x, mouse_y)
else
io.forceMousePosition(mouse_x, f_mouse_y)
end
end
end
function draw_cursor()
if no_bitmap == true then
-- no bitmap defined, so use normal lines
gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y - 20)
gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y + 20)
gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y + 20)
gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y - 20)
else
-- draw the bitmap centered on the spot
gr.drawMonochromeImage(mouse_bm, drawpos_x - mouse_bm_w, drawpos_y - mouse_bm_h, drawpos_x + mouse_bm_w, drawpos_y + mouse_bm_h)
end
end
function check_mouse_reset()
if mouse_reset_counter == nil then
mouse_reset_counter = 0
end
end
function force_mouse_control_status()
if io.MouseControlStatus == true then
mouse_reset_on_end = true
io.MouseControlStatus = false
end
end
function set_mouse_colors()
if mousecolors[1] == nil then
gr.setColor(0,64,220,196)
else
gr.setColor(mousecolors[1],mousecolors[2],mousecolors[3],mousecolors[4])
end
end
------------------------
--- end of functions ---
------------------------
]
$Application: FS2_Open
$State: GS_STATE_GAME_PLAY
$On Frame:
[
if boolscriptmouse == true then
-- check for center button reset...
check_mouse_reset()
-- get frametime (used to increment the timer)
frametime = ba.getFrametime()
-- make sure missiontime and old missiontime exist
if missiontime ~= nil then
missiontime_old = missiontime
end
missiontime = mn.getMissionTime()
-- if the setting changes make sure to reset it to false
force_mouse_control_status()
-- check if missiontime is actually running or not
if missiontime ~= missiontime_old then
-- after pause ends (ie. missiontime starts running again)
-- reset the mouse to the center
if end_of_pause == true then
io.forceMousePosition(mouse_center_x, mouse_center_y)
end_of_pause = nil
end
-- get control values
mouse_x = io.getMouseX()
mouse_y = io.getMouseY()
controls = ba.getControlInfo()
-- if center mouse button hasn't been been pressed in long enough and is being pressed now
-- reset the mouse
if mouse_reset_counter > 0.33 and io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
togglescriptmouse = not togglescriptmouse
if togglescriptmouse == true then
controls.Heading = old_h
controls.Pitch = old_p
mouse_x = mouse_center_x + (mousesensitivity * old_h)
mouse_y = mouse_center_y + (mousesensitivity * old_p)
io.forceMousePosition(mouse_x, mouse_y)
end
mouse_reset_counter = 0
else
mouse_reset_counter = mouse_reset_counter + frametime
end
if togglescriptmouse == true then
ba.setControlMode(LUA_FULL_CONTROLS)
io.MouseControlStatus = false
if mousecontrolmode == 1 then
-- make sure we aint gonna go off the boundaries...
do_boundaries_check(mousesensitivity, mouse_center_x, mouse_center_y)
-- end of boundaries check
-- define the color of the cursor
-- could use color inheritance!!!
set_mouse_colors()
-- get the actual control values
current_h = mouse_control_A(mouse_x, mouse_center_x, "x")
current_p = mouseinvert * mouse_control_A(mouse_y, mouse_center_y, "y")
-- increment, not replace the existing values
controls.Heading = current_h + controls.Heading
controls.Pitch = current_p + controls.Pitch
-- get draw position
drawpos_x = mouse_center_x + (current_h * mousesensitivity)
drawpos_y = mouse_center_y + (current_p * mousesensitivity)
-- draw cursor
draw_cursor()
end
else
ba.setControlMode(NORMAL_CONTROLS)
io.MouseControlStatus = true
old_h = cap_value(-1.0, 1.0, controls.Heading)
old_p = cap_value(-1.0, 1.0, controls.Pitch)
end
else
end_of_pause = true
end
end
]
$Application: FS2_Open
$On Mission End:
[
boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
io.MouseControlStatus = true
end
]
#End
Also, here's a sample configuration file:
data/config/mouse_script.cfg
Sensitivity: 250
Sensitivity Curve: 1.0
Control Mode: 1
Deadzone: 2
Mouse Invert: 0
Indicator Color: 255, 255, 0, 50
-
I've had a look for this file before myself and have been unable to find it. Pretty sure it's not in the wiki, or in two of the mouse script threads :(
-
Does the link in my signature for Mouse as Joystick have that file (or another workaround) included?
I have the scripts set, but the wiki page has no "mouse_ret_2.dds" file to download, therefore it defaults to the barely visible X that easily gets lost in the chaos of dogfights.
-
..You could make your own mouse_ret_2.dds
But let me see if I can find it. It's in WCS, right? I've got it here, just have to install it and find the file..
-
Sorry, but I can't seem to find it, at least in WCS 1.1.0.7822 :( Any idea where else it might be located?
-
No, unfortunately. Since they use fouse steering with an icon I thought it would be in their install directory.
I'll try poking them on their forums.
-
..You could make your own mouse_ret_2.dds
I have no idea how to do that.
-
I have an icon now, but where do I put it? I couldnt find anyhting about the file destination on the wiki page.
-
The script calls "gr.loadTexture" on mouse_ret_2.dds; so I'd put it in data/maps.
i.e.
<FSO_DIR> / <MOD_DIR> / data / maps / mouse_ret_2.dds
(create the nested folders data/maps if they don't already exist)
-
Moved to Maps. No effect.
Adding DL link for the dds file for anyone to look at.
https://mega.nz/#!l51WhC4C!pyH2jRuph4ognyF0UpoGSNPvBwyucs1T4M7aTRDBU4E
As it stands I cant save NTC Trinity because I can't see my steering recticle in the nebula, so it's like flying while drunk.
-
OK, there's some bad news. Putting the DDS in maps was fine; however the DDS itself is not fine:
Someone passed an extension to bm_load for file 'mouse_ret_2.dds'
DDS ERROR: Couldn't open 'mouse_ret_2.dds' -- Cannot load DDS if not power-of-2
and
$ file interface/mouse_ret_2.dds
interface/mouse_ret_2.dds: Microsoft DirectDraw Surface (DDS), 100 x 100, DXT3
However, the good news is I've resized it for you to 128x128 & FSO will load this file.
http://www.mediafire.com/download/dyjnww0sg6vsff8/mouse_ret_2.dds (http://www.mediafire.com/download/dyjnww0sg6vsff8/mouse_ret_2.dds)
Possibly back to bad news, it still doesn't exactly look hi-vis to me, so YMMV.
-
Yup. Apparently it's loading in that barely visible color.
Now I have to figure out how to change it's color.
Thanks for fixing it so far though
-
Is the color set by the HUD table file, or the .dds file itself? I'm wondering if the mouse cursor doesn't get converted to grayscale and then have its color set by the HUD table / interface settings. (Otherwise, to change it, you'd have to edit the file, which would be a PITA if it was, say, green, and you had your HUD set for red or blue.)
EDIT: In which case, if that was true, you'd probably want just a black-and-white (gray and white for transparency?) cursor.