Jump to content
The simFlight Network Forums

LUA String Manipulation - remove padding


Recommended Posts

Hi Pete,

 

 Hope you had a nice holiday / vacation.. I am working on a lua file where I need to substring/concatenate a string to the path from either 0x3C00 (.air) or 0x3E00 (fs path). Almost all the string functions I have found on the net seem to not work. I am assuming it has to do with the padding. For instance

 

path .. string -- does not work

string .. path -- does work cutting off the end ( - string.len)

 

I am assuming the console window and ipc.display automatically removes the padding prior to displaying - or something.. Am I at a 256 byte limit for manipulation? Really Stumped here.

 

I've tried a whole bunch of trim functions - Here  and  Here   none work and many fail.

 

Just thought of this as I'm typing - Instead of getting the whole 256 bytes from the offsets can I just get 100, 75 or 50 to give me some headroom? 

 

Thanks

-- SET DISPLAY TIME IN SECONDS ( 0 = NO SHOW ) 
local disptim = 3.00
-- END SETTINGS


-- GET AIR FILE PATH
path = ipc.readSTR(0x3C00,256)
length = string.len(path)

-- TRIM PADDING TRIES
newpath = string.gsub(path, "%s$", "")
--newpath = string.gsub(path, "0$", "0")

newlength = string.len(newpath) -- ALWAYS 256!

display = newlength .. "\n" .. newpath 


ipc.setowndisplay("TEST STRINGS", 0, 3, 50, 15)
ipc.display(display, 1, disptim)
ipc.sleep(disptim * 1000)

ipc.exit()
Link to comment
Share on other sites

I am working on a lua file where I need to substring/concatenate a string to the path from either 0x3C00 (.air) or 0x3E00 (fs path). Almost all the string functions I have found on the net seem to not work. I am assuming it has to do with the padding

 

By "padding" I assume you mean the characters beyond the zero string terminator?

 

I am assuming the console window and ipc.display automatically removes the padding prior to displaying - or something

 

No. Those are written in C of course, and strings in C have a zero terminator. So whatever is beyond the zero is not part of the string as far as they are concerned.

 

Am I at a 256 byte limit for manipulation?

 

No, but I think 256 is either the limit, or close to the limit, for full pathnames in the Windows file syatem functions. So if you are planning to use the result for file system access you'd need to keep it down. However, if this is about genuine files and paths then the result is bound to fit, for the same reason.

 

In Lua "strings" are really only byte arrays, so can be as long as you likeand there are no special characters -- 0 is just a null, not a terminator.

 

So, in order to concatenate these zero-terminated strings you need to find the position of the zero and use the length to that to extract the substring for concatenation. You only need to do this for the first string of course.

 

Regards

Pete

Link to comment
Share on other sites

 

 

Looking at your example code,  I realise my first reply might not have been so helpful. You seem to be intent on using gsub. And also confusing the charact "0" with the zero value, "\0". (The ASCII character 0 is actualy hex 30, or decimal 48 -- certainly not zero).

 

Try using find, as in:

 

newlength = string.find(path, "\0", 1, true)

 

then you can take the substring of length newlength-1 (really you should check that newlength is not zero first, of course -- but if it is then the entire 256 bytes are 'path' and you are stuck).

 

Does that help?

 

Regards

 

Pete

Link to comment
Share on other sites

Pete,

 

 WORKS GREAT! Thank You. Now that they are in a byte (bite LOL  :rolleyes: ) size chunk all the string manipulation I need can be / is done. (Below) A couple more questions if I may?

 

1. I can test this, just wondered if you know off the top if the following works - If the data in an .air file is changed but the name of the .air file is not, then the aircraft is reloaded by .flt file or by the command "reload user aircraft", does the new data in the .air file get read?  

 

2. This may be beyond my knowledge but, can the "add menu" facilities at offset 0x2FE0 be done with Lua? If it can I just may give it a try.

 

Thanks again,

Happy Holidays, 

-- SET DISPLAY TIME IN SECONDS ( 0 = NO SHOW ) 
local disptim = 2
-- END SETTINGS

-- RUN, DISPLAY and END  
function display(path, disp, func)
	ipc.setowndisplay("SHRS F-111", 41, 3, 18, 0)
		if func == 1 then
			ipc.display(disp, 1, disptim)			
		else
			ipc.display(disp, 1, disptim)
			ipc.sleep(250)
			local handle, error = ext.runif(path)	
				if handle == 0 then
					if error == -1 then
						ipc.display("ALREADY RUNNING", 1, disptim)
					else
						ipc.display("MALFUNCTION " .. error, 1, disptim)
					end											
				end						
		end		
	 ipc.sleep(disptim * 1001)
	 ipc.exit()
end

-- ADD TO PATH 
local eggs = "SHRS F-111 Aardvark" .. string.char(92) .. "SHRS F-111 Configurator.exe"

-- GET .AIR FILE PATH
local airf = ipc.readSTR(0x3C00,256)

-- GET LENGTHS
local unused, length = string.find(airf, "\Airplanes", 1, true)

-- CHECK FOR NULL PATH
if length < 1 then
	display("OOPS", "ERROR FINDING PATH", 1)
end

-- MAKE THE FULL STRING AND SEND
local path = string.sub(airf, 1, length + 1) -- add trailing "\"
path = path .. eggs
display(path, "STARTING CONFIGURATOR", 0)

-- JUST IN CASE
ipc.exit()

Link to comment
Share on other sites

1. I can test this, just wondered if you know off the top if the following works - If the data in an .air file is changed but the name of the .air file is not, then the aircraft is reloaded by .flt file or by the command "reload user aircraft", does the new data in the .air file get read? 

 

I don't think it does, because it will be cached -- but I'm not sure about that. I've never delved into it really. Whenever I've changed something in a Aircraft.CFG file I've always changed aircraft and back again to make sure it reads it anew.

 

2. This may be beyond my knowledge but, can the "add menu" facilities at offset 0x2FE0 be done with Lua? If it can I just may give it a try.

 

I can't think of any reason they can't work from Lua. They certainly work even from other PCs using WideFS.

 

Regards

Pete

Link to comment
Share on other sites

 I forgot to add, it's trivial and I may be wrong. On pg. 13 of FSUIPC Lua Library.pdf should "isrunning()" be "ext.isrunning()" ?

 

Yes, of course. Gradually little errors in the document are coming to light. I've corrected it here so it will be okay on the next release.

 

Thanks,

Pete

Link to comment
Share on other sites

Pete,

 

   I gave the add-on menu a go and it works! Kinda tough for me but I be happy camper! I have one problem though, it is killing the menu when needed. ( See the 3rd lua under the  function cleanup() ) It's really not that big of a deal except when I change from one of our own aircraft to another one of our own. The menu doubles up until the timer on the first menu entry runs out. Really not that bad, would like to do better. I was thinking of using the next set back of "user memory" slots ( as used in the # 2 lua ) to store the slot address and check if it is our entry on reload then continue to use if it is. ( sounds right? ) Also if you have a few minutes could you check my #3 to make sure I did all the checking etc.. needed and nothing being done really bad? Kinda scared (LOL) because i would like to release it to our users.

 

  Hope you do not mind but I posted all three of the .lua(s) to give you an idea of the whole package I am trying to create. The main concentration is on #3. My project head honcho has always wanted to have these functions but I am incapable of C/C++. Believe me, I tried a couple of dozen tries to do a "Hello World" . Maybe in a few years LOL. Also the requirement for our package is the free version of FSUIPC, this is the best i can do and will be released as a User Contribution for our aircraft package with no official but rather private support. 

 

Lua 1 - Provides the end user of keyboard / joystick activation of our configuration program. It also acts as a slave to #s 2 & 3.

Lua 2 - Provides Automation.

Lua 3 - "The" menu.

 

Any combination of them could be used depending on preferences.

 

And again, trivial and just an idea... It has to do with the console debugging window. If the console window is opened but minimized when FSX is closed the FSUIPC.ini gets written with values like -  ConsoleWindow=-32000,-32000,-31840,-31973 . Was wondering if there is not too much of a deal maybe do something, if caught, make it something like -  ConsoleWindow=0,0,500,500 ? When FSX is restarted it is impossible to get the window back without closing FSX again and editing FSUIPC.ini manually. Again trivial, I keep hitting myself in the face every time I do it. Pretty swollen at this point LOL! :mrgreen:   (Really like seeing what FSUIPC is doing on FSX start :razz:  ) 

 

Again Thank - You as always,

None of the below could've been done without your help. 

Programming stuff in FS = #1 Hobby,

Flying in FS when everything works = #2 Hobby 

 

Roman

 

#1

--[[ SHRS CFGR8R_1.lua - This lua file provides the ability to assign a keyboard key or a joystick button (or both) to start the configurator. This lua file is a "one shot", meaning it is only run when commanded to and it exits itself. It is commanded to run after being setup in the FSUIPC dialog under the "Keys Presses" tab or "Buttons + Switches" tab for either the keyboard or joystick (or both). Once run it starts the F-111 configurator. ]]

-- SET DISPLAY TIME IN SECONDS ( 0 = NO SHOW, WHOLE NUMERS ONLY ) 
local disptim = 2
-- END SETTINGS

function display(path, disp, func)
	ipc.setowndisplay("SHRS F-111 Configurator", 41, 3, 18, 0)
		if func == 1 then
			if disptim >= 1 then
				ipc.display(disp, 1, disptim)
			end			
		else
			if disptim >= 1 then
				ipc.display(disp, 1, disptim)
			end
			ipc.sleep(250)
			local handle, error = ext.runif(path)	
			if handle == 0 then
				if error == -1 then
					if disptim >= 1 then
						ipc.display("ALREADY RUNNING!", 1, disptim)
					end
				else
					if disptim >= 1 then
						ipc.display("MALFUNCTION! = " .. error, 1, disptim)
					end
				end											
			end						
		end		
	 ipc.sleep(disptim * 1001)
	 ipc.exit()
end
local eggs = "SHRS F-111 Aardvark" .. "\\" .. "SHRS F-111 Configurator.exe"
local airf = ipc.readSTR(0x3C00,256)
local unused, length = string.find(airf, "\Airplanes", 1, true)
if length < 1 then
	display("OOPS", "ERROR FINDING PATH!", 1)
end
local path = string.sub(airf, 1, length + 1)
path = path .. eggs
display(path, "STARTING........", 0)
ipc.exit()
 

#2

--[[ SHRS CFGR8R_2.lua - This lua file adds automation. It is a "one shot" like above except it is only run when FSX if first started or when there is an aircraft change, it also exits itself.  When FSX is first started and if the saved flight or flight selection loads the SHRS F-111 (any sub model) the configurator will run. Also, when there is an aircraft change from anything other than the SHRS F-111 to the SHRS F-111 (any sub model) the configurator will run. The configurator will not start automatically when changing between SHRS F-111 models as it may have been commanded for an aircraft change by the configurator itself or the F-111 was configured as a "Default Release". Therefore the configurator is not necessary.
(MAY CHANGE AND HAVE THE CONFIGURATOR WRITE A BIT TO SHOW THAT IT HAS INDEED COMMANDED THE AIRCRAFT CHANGE)  
Auto run under [Auto] in FSUIPC.ini  	
NOTE -  SHRS CFGR8R_1.lua is required in the modules folder although it does not need (optional) to be configured for keyboard or joystick usage. ]]

local mem = 0x66FF -- UNUSED "USER" MEMORY SLOT IN FSUIPC, IN THIS CASE THE ENDING BYTE OF TOTAL AREA, POSSIBLY PREVENTING CONFLICTS FROM OTHER USERS
local airf = ipc.readSTR(0x3C00,256)
local past = ipc.readUB(mem)
local starting, ending = string.find(airf, "\SHRS F-111 Aardvark", 1, true)
if (starting == nil) or (ending == nil) then
	starting = 1
	ending = 1
end
local string = string.sub(airf, starting, ending)
if string == "SHRS F-111 Aardvark" and past == 0 then
	ipc.writeUB(mem, 1)		
	ipc.macro("Lua SHRS CFGR8R_1")
else
	if string ~= "SHRS F-111 Aardvark" then
		ipc.writeUB(mem, 0)
	end	
end	
ipc.exit() 

#3

--[[ SHRS CFGR8R_3.lua - This lua file adds a menu for the starting the configurator in the "Add-ons" menu of FSX. It can be set to show the menu at all times ( handy when using "Force Reload via Current Flight ) or to show always. If "show always" or the SHRS F-111 is selected under the setting "F-111 only" it is always running (very sparse usage), otherwise under the setting "F-111 only" and in another non F-111 aircraft it exits immediately and will restart and check again on an aircraft change.     
Auto run under [Auto] in FSUIPC.ini  	
NOTE -  SHRS CFGR8R_1.lua is required in the modules folder although it does not need (optional) to be configured for keyboard or joystick usage. ]]

-- SHOW ONLY FOR F-111 OR ALWAYS
local showme = 0 -- Show only for F-111 = 0, Show always = 1
-- END SETTINGS

-- PREVENT NIL ERRORS
local addr = 0 
local time = 0
local slot = 0
local time = 0	 
	
-- ACTIVATE BASED ON THE ABOVE USER SETTINGS IF F-111 ONLY
if showme == 0 then
	local airf = ipc.readSTR(0x3C00,256)
	local starting, ending = string.find(airf, "\SHRS F-111 Aardvark", 1, true)
	if (starting == nil) or (ending == nil) then -- PREVENT NIL ERRORS IF NOT OUR F-111 AIRCRAFT, RETURNS ROOT FSX DRIVE LETTER
		starting = 1
		ending = 1
	end
	local string = string.sub(airf, starting, ending)	
	if string == "SHRS F-111 Aardvark" then
		showme = 1
	else
		ipc.exit()
	end	
end 

-- DO THE ADD MENU WORK
if showme == 1 then
	for i = 0x3210, 0x32D0, 0x4 do	
		local data = ipc.readUD(i)		
		if data == 0 then
			addr = i
			-- ipc.display(slot .. "    " .. addr, 1, 3) -- CHECK PROPER SLOT AND ADDRESS
			ipc.writeUD(addr, 0x0000ffff) 
			ipc.writeSTR(0x2FE1, "&SHRS F-111 Configurator ...")
			ipc.writeUB(0x2FE0, slot)	
			break		
		end
		slot = slot + 1	
	end	
end

-- REFRESH THE ADD ON MENU AND CHECK FOR MENU SELECTED 
function refresh()
	if showme == 1 then
		local trigr = ipc.readUB(addr + 0x3)
		if trigr == 1 then
			ipc.writeUB(addr + 0x3, 0)
			ipc.macro("Lua SHRS CFGR8R_1")
		end        
		time = time + 1
		if time == 10 then
			time = 0
			ipc.writeUD(addr, 0x0000ffff)
		end
	end 
end

-- PREVENT DOUBLING UP ON THE MENU AND GENERAL SWEEPING
function cleanup()
	if addr ~= 0 then -- KEEP FROM CONTINUNING IF AN ADDRESS WAS NEVER SUPPLIED
		ipc.writeUD(addr, 0x00000000) -- WRITE ZERO TO THE TIMER AT SLOT ADDRESS
		-- ipc.writeSTR(0x2FE1, "0") -- WRITE ZEROS TO THE ADD ONS OFFSET, PROBABLY NOT GOOD
		-- ipc.writeUB(0x2FE0, 0)  -- WRITE ZEROS TO THE ADD ONS OFFSET, PROBABLY NOT GOOD
		event.cancel("refresh") -- ANOTHER TRY TO GET RID OF THE MENU, ON AIRCRAFT CHANGE, WHEN NOT REQUESTED
		ipc.sleep(1000) -- CANT GET THE ABOVE TO WORK, MAYBE MORE TIME?, PROBABLY DOESN'T WORK AS LUA IS BEING KILLED	
	end
end

event.terminate("cleanup")
event.timer(1000, "refresh") 

post-1722-0-62198700-1386307221_thumb.jp

Link to comment
Share on other sites

 I gave the add-on menu a go and it works! Kinda tough for me but I be happy camper! I have one problem though, it is killing the menu when needed. ( See the 3rd lua under the  function cleanup() ) It's really not that big of a deal except when I change from one of our own aircraft to another one of our own. The menu doubles up until the timer on the first menu entry runs out. Really not that bad, would like to do better.

 

Why not use the facility to remove the menu immediately (see para starting "When you no longer need the menu entry ....").

 

And again, trivial and just an idea... It has to do with the console debugging window. If the console window is opened but minimized when FSX is closed the FSUIPC.ini gets written with values like -  ConsoleWindow=-32000,-32000,-31840,-31973 . Was wondering if there is not too much of a deal maybe do something, if caught, make it something like -  ConsoleWindow=0,0,500,500 ? When FSX is restarted it is impossible to get the window back without closing FSX again and editing FSUIPC.ini manually. Again trivial, I keep hitting myself in the face every time I do it. Pretty swollen at this point LOL! :mrgreen:   (Really like seeing what FSUIPC is doing on FSX start :razz:  )

 

 

Is it always -32000,-32000? I can't simply change any negatives because folks with multiple screens and a centre one as default can place windows in negative coordinate territory.

 

Better, I think, if I can, is detect that it is minimised and not change whatver coordinates were last saved.

 

Regards

Pete

Link to comment
Share on other sites

Pete,

 

 Finally got it... A fresh day with fresh brain cells helped. Was writing to zero to the correct slot. I reckon lua cleaned itself up before the write could be made. 

 

Thank You,

Roman

 

 

 

function cleanup()
if addr ~= 0 then          -- KEEP FROM CONTINUNING IF AN ADDRESS WAS NEVER SUPPLIED IE FOUND NO SLOT
ipc.writeUD(addr, 0x0)  -- WRITE ZERO TO THE SLOT ADDRESS
end
end
 
-- event.terminate("cleanup")    -- ORIGINAL, ONLY 55 MSECS TO GET STUFF DONE, FUNCTION CALLED, NOT ENOUGH TIME TO WRITE BEFORE EXIT
event.sim(FLIGHTLOAD, "cleanup") -- WORKS PERFECTLY
event.sim(AIRCRAFTCHANGE, "cleanup")  -- WORKS PERFECTLY

 

 

1974115 LUA.0: Terminate event: calling "cleanup" in "G:\FSX\Modules\SHRS CFGR8R_3.lua"
1974115 LUA.0: G:\FSX\Modules\SHRS CFGR8R_3.lua:66 = ipc.writeUD(addr, 0x0)  -- WRITE ZERO TO THE SLOT ADDRESS WAS CALLED BUT NEVER WORKED
Link to comment
Share on other sites

1974115 LUA.0: Terminate event: calling "cleanup" in "G:\FSX\Modules\SHRS CFGR8R_3.lua"

1974115 LUA.0: G:\FSX\Modules\SHRS CFGR8R_3.lua:66 = ipc.writeUD(addr, 0x0)  -- WRITE ZERO TO THE SLOT ADDRESS WAS CALLED BUT NEVER WORKED

 

Hmm. That's strange. When I get a moment I'll check into that. Should be able to do that easily. 55 mSecs is a lifetime in any case, and if the command is actually processed it should operate. Maybe I'm checking the terminate flag BEFORE execution rather than AFTER -- but even then, there's loads of time.

 

Pete

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.