Difference between revisions of "Script - Scripted Mouse"
From FreeSpace Wiki
m (new script) |
Wookieejedi (talk | contribs) m (update to modern link) |
||
(5 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | == | + | |
− | Draws mouse flight icon and modifies the mouse controls | + | == '''This script is now outdated and the modern version is:''' == |
+ | [https://www.hard-light.net/forums/index.php?topic=97931.0 Modern Mouse as Joystick script] | ||
+ | |||
+ | |||
+ | Draws mouse flight icon and modifies the mouse controls. | ||
==Table entry== | ==Table entry== | ||
Line 11: | Line 15: | ||
[ | [ | ||
− | -- | + | --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 | -- find any instances of the keyword | ||
− | key_s, key_e = line_to_parse:find(keyword) | + | keyword = keyword:lower() |
+ | local key_s, key_e = line_to_parse:find(keyword) | ||
-- if we cant find a thing | -- if we cant find a thing | ||
Line 26: | Line 42: | ||
end | 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 | |
− | |||
− | -- find | + | --- 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 | -- stuff the array | ||
− | for p in line_to_parse:gmatch( | + | 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 | end | ||
return r | return r | ||
end | end | ||
− | function | + | --- function to parse things |
− | + | function parse_entry(keyword, mousefile, type, use_same_line) | |
− | if | + | local new_entry = nil |
− | + | local return_val | |
− | if | + | 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 | ||
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 | end | ||
− | -- if | + | end |
− | elseif | + | 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("Boundary Limit:", mousefile, "n", use_same_line) | ||
+ | if temp_val == -2 then | ||
+ | break | ||
+ | elseif temp_val ~= -1 then | ||
+ | ba.print("\tBoundary Limit: " .. temp_arr[1] .. "\n") | ||
+ | mouseboundaries = 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 | ||
− | -- | + | end |
− | + | end | |
− | + | --NEW PARSER | |
− | + | ||
− | + | function verify_mouse_data() | |
− | end | + | -- make sure we have a number in deadzone var and not nil |
− | -- if | + | if mousedeadzone == nil then |
− | + | mousedeadzone = 0 | |
− | mouseboundaries = | + | 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 if boundaries are valid | ||
+ | if mouseboundaries == nil then | ||
+ | mouseboundaries = 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() | ||
+ | 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 | else | ||
− | + | no_bitmap = true | |
end | end | ||
end | end | ||
Line 116: | Line 313: | ||
----------------------------------------------------------------------- | ----------------------------------------------------------------------- | ||
filename_mouse = "mouse_script.cfg" | filename_mouse = "mouse_script.cfg" | ||
− | boolmousefileOK = cf.fileExists(filename_mouse, "data/ | + | boolmousefileOK = cf.fileExists(filename_mouse, "data/config/", true) |
boolscriptmouse = false | boolscriptmouse = false | ||
Line 132: | Line 329: | ||
-- open the file in read only mode | -- open the file in read only mode | ||
− | mousefile = cf.openFile(filename_mouse, "r | + | mousefile = cf.openFile(filename_mouse, "r") |
− | + | -- do the parsing thing | |
− | -- | + | parse_mousefile(mousefile) |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
-- all data read.. time to close the file | -- all data read.. time to close the file | ||
mousefile:close() | mousefile:close() | ||
Line 152: | Line 341: | ||
boolscriptmouse = true | boolscriptmouse = true | ||
ba.setControlMode(LUA_FULL_CONTROLS) | ba.setControlMode(LUA_FULL_CONTROLS) | ||
+ | verify_mouse_data() | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
else | else | ||
ba.warning("Scripted mouse's init failed") | ba.warning("Scripted mouse's init failed") | ||
Line 200: | Line 349: | ||
ba.warning("File '" .. filename_mouse .."' not found") | ba.warning("File '" .. filename_mouse .."' not found") | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
------------------------ | ------------------------ | ||
Line 277: | Line 418: | ||
io.forceMousePosition(mouse_x, f_mouse_y) | io.forceMousePosition(mouse_x, f_mouse_y) | ||
end | 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_center_x = io.getMouseX() | ||
+ | mouse_center_y = io.getMouseY() | ||
+ | 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 | end | ||
Line 282: | Line 459: | ||
--- end of functions --- | --- end of functions --- | ||
------------------------ | ------------------------ | ||
+ | |||
+ | ] | ||
+ | |||
+ | $Application: FS2_Open | ||
+ | $State: GS_STATE_GAME_PLAY | ||
+ | $On Frame: | ||
+ | |||
+ | [ | ||
if boolscriptmouse == true then | if boolscriptmouse == true then | ||
-- check for center button reset... | -- check for center button reset... | ||
− | + | check_mouse_reset() | |
− | |||
− | |||
− | |||
− | |||
-- get frametime (used to increment the timer) | -- get frametime (used to increment the timer) | ||
Line 301: | Line 482: | ||
-- if the setting changes make sure to reset it to false | -- if the setting changes make sure to reset it to false | ||
− | + | force_mouse_control_status() | |
− | |||
− | |||
− | |||
-- check if missiontime is actually running or not | -- check if missiontime is actually running or not | ||
Line 342: | Line 520: | ||
-- define the color of the cursor | -- define the color of the cursor | ||
− | + | -- could use color inheritance!!! | |
− | + | set_mouse_colors() | |
− | |||
− | |||
− | |||
-- get the actual control values | -- get the actual control values | ||
Line 363: | Line 538: | ||
-- draw cursor | -- draw cursor | ||
− | + | draw_cursor() | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
else | else | ||
Line 395: | Line 563: | ||
==Configuration file== | ==Configuration file== | ||
− | Filename '''mouse_script.cfg''', placed into '''.../data/ | + | Filename '''mouse_script.cfg''', placed into '''.../data/config/''' directory |
<pre>Sensitivity: 350 | <pre>Sensitivity: 350 | ||
Sensitivity Curve: 1.5 | Sensitivity Curve: 1.5 | ||
Line 415: | Line 583: | ||
==Additional files== | ==Additional files== | ||
− | Script will accept '''mouse_ret_2.dds''' as the mouse indicator but should the effect be missing the script should revert to simple 2d draw icon (icon is automatically centered). | + | Script will accept '''mouse_ret_2.dds''' as the mouse indicator, but should the effect be missing, the script should revert to simple 2d draw icon (icon is automatically centered). |
+ | |||
+ | 128x128 res file here: http://www.mediafire.com/download/dyjnww0sg6vsff8/mouse_ret_2.dds | ||
[[Category:Scripting_Examples]] | [[Category:Scripting_Examples]] |
Latest revision as of 19:00, 26 February 2024
Contents
This script is now outdated and the modern version is:
Modern Mouse as Joystick script
Draws mouse flight icon and modifies the mouse controls.
Table entry
For example script_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("Boundary Limit:", mousefile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("\tBoundary Limit: " .. temp_arr[1] .. "\n") mouseboundaries = 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 if boundaries are valid if mouseboundaries == nil then mouseboundaries = 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() 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 -- if file exists if boolmousefileOK then -- reset all the variables to nil mousesensitivity = nil mousesensitivitymode = nil mousecontrolmode = nil mousedeadzone = nil mouseinvert = nil mouseboundaries = 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(limit) f_mouse_x = nil f_mouse_y = nil -- do we go over width limits if mouse_x <= limit then f_mouse_x = limit elseif mouse_x >= (scr_width - limit) then f_mouse_x = scr_width - limit end -- do we go over height limits if mouse_y <= limit then f_mouse_y = limit elseif mouse_y >= (scr_height - limit) then f_mouse_y = scr_height - limit end -- 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_center_x = io.getMouseX() mouse_center_y = io.getMouseY() 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 -- increment the center mouse button down counter if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then mouse_reset_counter = mouse_reset_counter + frametime else mouse_reset_counter = 0 end -- if center mouse button has been pressed long enough -- reset the mouse if mouse_reset_counter > 0.1 then io.forceMousePosition(mouse_center_x, mouse_center_y) mouse_reset_counter = 0 end -- get control values mouse_x = io.getMouseX() mouse_y = io.getMouseY() controls = ba.getControlInfo() if mousecontrolmode == 1 then -- make sure we aint gonna go off the boundaries... do_boundaries_check(mouseboundaries) -- 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 center_x = scr_width / 2 center_y = scr_height / 2 drawpos_x = center_x + (current_h * 300) drawpos_y = center_y + (current_p * 300) -- draw cursor draw_cursor() 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
Configuration file
Filename mouse_script.cfg, placed into .../data/config/ directory
Sensitivity: 350 Sensitivity Curve: 1.5 Control Mode: 1 Deadzone: 2 Mouse Invert: 0 Boundary Limit: 20 Indicator Color: 255, 255, 0, 64
- Sensitivity is basically defines the amount of pixels from the center of the screen that the script will read (limited from 100 to 600)
- Sensitivity Curve is exponent for the value
- Control Mode is just option to toggle the - possible, not yet implemented - alternate control modes on
- Deadzone defines the deadzone for the control input
- Mouse Invert allows mouse controls to be inverted
- Boundary Limit defines the limit for the cursor from the edge of the screen.
- Indicator Color defines the used draw color of the mouse flight indicator
Recommendations... (sensitivity + deadzone + boundary limit) * 2 should be greater than the smaller dimension of the screen.
Additional files
Script will accept mouse_ret_2.dds as the mouse indicator, but should the effect be missing, the script should revert to simple 2d draw icon (icon is automatically centered).
128x128 res file here: http://www.mediafire.com/download/dyjnww0sg6vsff8/mouse_ret_2.dds