Jump to content

Lockon mapeditor, some maths help needed


Recommended Posts

Posted

Hi guys,

 

A non-maths mind needs some help with a mathmetical puzzle.

 

I am working on a GUI editor project for lockon, whereby one could edit the lockon world, to add objects such as shelters, buildings etc. onto specific locations. I need some help.

 

Whats puzzling me is how to calculate scaling from screen pixel X to realworld X.

 

I have taken a screenshot of the airbase Khersones, determined the topleftW, toprightE, bottomleft, bottomright coordinates for both long-/and lattitude as per lo-mac missioneditor. It doesnt really matter the size of the bitmap.

 

The following is kinda a description of my question statement:

* if the X-pos on 1 pixel then the realworld lattitude West is 33.2254 in addition,

* if X-pos is at 800 is then the realworld lattitude East is 33.4705

 

Question: what is the realworld scled (X-position) value of 1 pixel?

 

the lomac missioneditor already has this built in. Go to the missioneditor move the mouse in the lo-mac mapeditor, or also get Google Earth and see for yourself.

 

TIA!

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted
The following is kinda a description of my question statement:

* if the X-pos on 1 pixel then the realworld lattitude West is 33.2254 in addition,

* if X-pos is at 800 is then the realworld lattitude East is 33.4705

 

Question: what is the realworld scled (X-position) value of 1 pixel?

i believe it should be:

 

(33.4705 - 33.2254) / (800 - 1) = 0.00030676 °/pixel

 

so that the longitude of the nth pixel from the left would work out to be:

 

longitude_n = 33.2254 + ( n x 0.00030676)

 

where n goes from 0 -> 799

 

I'm sure you've already considered this but beware of your zoom level when taking the screenshots.

 

Hope this is correct and helps.

  • Like 1
Posted

without using Universal Transversal Mercator Projection maths or what I call pseudo-LockOn-UTM you will never accomplish a precise plot...

 

The reason for this is that for example

 

10deg10Min10sec N 20deg20Min00sec E and

10deg10Min10sec N 20deg30Min00sec E and <+10Min E

10deg10Min10sec N 20deg40Min00sec E <+10Min E

 

are not in one straight line but will resemble something like a very narrow triangle.

 

Travelling from East to West on the same longitude you will not travel on a straight line but on a curve...

 

But if you plan to do what you are saying, we might join forces if u like...

Write me and explain in some more detail what u want to do... Do u actually plan to make a new scenery File Editor ? Which programming/scripting language do you consider ?

 

Zillion

Posted

jabog, I ain't no cartographer (although i did start a mapping project http://forum.lockon.ru/showpost.php?p=147937&postcount=20). I must admit though that i didn't take the geometrical phenomenon you're talking about into consideration beacuse I thought it would be negligible on the map scale we're looking at. I didn't look at the actual numbers though.

 

So what i'm getting at is: is it or isn't it negligible? (where the meaning of negligible varies depending on the application)

Posted

hey THANX!!:p :icon_supe

 

It was great thanx :).

 

Now does any1 perhaps know how to draw onto a map?

 

I am coding in visual studio 2003 programming language is C#..

 

I'd like to add objects onto the bitmap.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

Hi Zillion

 

Travelling from East to West on the same longitude you will not travel on a straight line but on a curve...

 

 

You wrote about such a thing in the ATC thread.

 

But if you plan to do what you are saying, we might join forces if u like...

 

SURE :).

 

Write me and explain in some more detail what u want to do...

 

For now my idea is to make a editor which has a GUI. One could modify the \Bazar\Terrain\Scenes\*.scn files. Swingkid has provided me with a tool to extract a .scn to text for manipulation. That idea i want to extend further.

 

The reasoning for my idea is because of something Swingkid and 666th_birdy are/were working on.

 

The main aims of this scenes file editor, a first release:

* Allow a user to open a lomac .scn-file.

* Allow a user to add/remove user-defined objects onto any geografical location in the lo-mac world.

* Save this as a custom scenes metadata XML, for later retrieval.

* Then, append the custom scenes metadata onto high.scn for example.

 

future versions;

* Allow the user to add objects in groups onto the map, like create a woodland of trees.

* Have templates for towns, user could click on a map area and point where to add a town.

* Relocate 1 or 2 airbases from the Krim to Turkey, Bulgaria.

 

Waaaay into the future;

* It can be a missioneditor, allowing COPYING and pasting of units, great for multiplayer missions.

 

 

Do u actually plan to make a new scenery File Editor ? Which programming/scripting language do you consider ?

 

Zillion

 

I see a possibility of a custom lo-mac Missioneditor as a distinct real possibility, though longterm. The current missioneditor really needs a overhaul!

 

The programming environment is M$ VS2003.NET, coding in c#. Though at home i use VS2005 Beta 2. If you dont have it, go grab the "free" express edition from the msdn website.

 

Do you have any ideas yourself, your help will be greatly appreciated :cool:

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

I`m drunk...

 

But well... That sounds very interesting what you`re planning threre... I`m currently working on a Mission Editor myself... Well actually it was someone else who showed me that the Mission File .mis is essentially a XML file wrapped in some kind of Header since it uses Characters which are illegal in ordinary XML... from what I understood and seen...

I wrote a java class Chooser which uses the java .awt and .swing classes to bring up a FileSystem file chooser and split any Mission File in Header and XML and a java class Saver which brings up a Save Dialog to Join XML and header to regenerate a .mis File which actually still works... The Mission XML itself is like xml.... hierarchical and looks something like this:

<LockOnMissions>

<Groups>

<Routes>

<RoutePointID>

<Positions>

 

Well... I`m not fit in C++ until now I`ve only been working with java and Actionscript, the latter being the Scripting Language of Flash which is a java script based Object Orientated language and until now my Development environment... As said before I`m only slowly fiddling myself into File Choosers and User Interfaces with java but that will take more time...

 

As for the Position conversion from lat/long to UTM it is actually quite heavy math stuff... you can either use the Formula that Valery Blazhnov from the Lock On Development Team sent me in this Thread http://forum.lockon.ru/showthread.php?t=7358

 

If you are a programmer then the following C++ code may help you:

const float zeroX = 5000000.f; // Real coordinates beginning

const float zeroZ = 6600000.f;

 

const float centerX = 11465000.f - zeroX; // Circle center

const float centerZ = 6500000.f - zeroZ;

 

const float pn40x24_X = 4468608.57f - zeroX; // point 40dgN : 24dgE

const float pn40x24_Z = 5730893.72f - zeroZ;

 

const float pn48x24_X = 5357858.31f - zeroX; // point 48dgN : 24dgE

const float pn48x24_Z = 5828649.53f - zeroZ;

 

const float pn40x42_X = 4468608.57f - zeroX; // point 40dgN : 42dgE

const float pn40x42_Z = 7269106.20f - zeroZ;

 

const float pn48x42_X = 5357858.31f - zeroX; // точка 48dgN : 42dgE

const float pn48x42_Z = 7171350.00f - zeroZ;

 

// distances from the circle center to 48dgN and 40dgN

const double lenNorth = sqrt((pn48x24_X-centerX)*(pn48x24_X-centerX) + (pn48x24_Z-centerZ)*(pn48x24_Z-centerZ));

const double lenSouth = sqrt((pn40x24_X-centerX)*(pn40x24_X-centerX) + (pn40x24_Z-centerZ)*(pn40x24_Z-centerZ));

const double lenN_S = lenSouth - lenNorth;

 

const double RealAngleMaxLongitude = atan (((double)pn40x24_Z - centerZ)/(pn40x24_X - centerX)) * 180.f / PI;

 

// Map bounds. Degrees!

const float EndWest = 24.f;

const float EndEast = 42.f;

const float EndNorth = 48.f;

const float EndSouth = 40.f;

const float MiddleLongitude = (EndWest + EndEast) / 2;

 

const float ToLengthN_S = (float)((EndNorth - EndSouth) / lenN_S);

const double ToAngleW_E = (MiddleLongitude - EndWest) / RealAngleMaxLongitude;

const double ToDegree = 180. / PI;

 

void GetCoords(double inLatitudeGrad, double inLongitudeGrad, float &outX, float &outZ)

{

double realAng = (inLongitudeGrad - MiddleLongitude) / ToAngleW_E / ToDegree;

double realLen = lenSouth - (inLatitudeGrad - EndSouth) / ToLengthN_S;

outX = centerX - realLen * cos (realAng);

outZ = centerZ + realLen * sin (realAng);

}

__________________

Valery Blazhnov

Lock On Development Team

Eagle Dynamics

 

This Thread might also be interesting for you:

http://forum.lockon.ru/showthread.php?t=7010

 

Or you can use the real UTM conversion which is even more heavy... You can see it in my attached file of this Thread

http://forum.lockon.ru/showthread.php?t=8493&page=14

 

Or here...

http://www.polymoon.org/tobi/privat/WSG842UTM.swf

 

Well all I want to accomplish is a Mission Editor capable of changing the waypoints snapping to reallife VOR`s and DME`s for planes aswell as assigning the same waypoints to whole Groups of Clients to save the Mission Builder the mouse kilometers when making multiplayer missions...

 

But since you told me the scn file is also essentially XML I`m defintily going to take a look at it and I`m very happy to help where I can.

 

@lunera

 

The deviation can be serveral hundert kilometers in the worst case...

 

regards

 

Zillion

Posted

Zillion, please PM me. Gimme your e-mail adress too. I have a pre-release version available for getting-an-idea :).

 

U need the M$ Dotnetframework to run it.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

Hi!

 

 

As for the Position conversion from lat/long to UTM it is actually quite heavy math stuff... you can either use the Formula that Valery Blazhnov from the Lock On Development Team sent me in this Thread http://forum.lockon.ru/showthread.php?t=7358

regards

 

Zillion

 

Current status:

* The app can load a bitmap file.

* Allow a user too add, delete or edit objects onto the bitmap at specific coordinates.

* Save this user additions as a template XML file.

* Reload the template back for later editing.

* Export these objects as a scene metadata file, ready for processing by Swingkid's scenedit2.exe proggy.

 

Future editions:

* Allow to convert a saved lockon mission file to a scene.

* A custom mission editor...?

 

The readme file:

USAGE:
Take a real world map from lockon, or <a href="http://earth.google.com">Google Earth</a>.Make a screenshot of the section you want to populate with objects in lo-mac. Look at the examples Sukhumi.jpg.Note down the topleft, topright etc realword coordinates, then add it into mapeditorMeta.xml, see examples.
Edit the mapeditorMeta.xml.Your screenshots must be relative to directory '" + AppDomain.CurrentDomain.BaseDirectory + "
Open a map, from the Editor menu, then click on the bitmap to add some objects.
Start adding lockon objects, such as trees, static objects on to the map.<br>
Save to a file if u want.
Use [b]<b>Export</b>[/b] to create a text file, which you must manually append to a file created with scnedit.exe
Recompile a new scene file using Swingkid' scnedit2.exe util.
Start Lockon: Flaming Cliffs and check out your new masterpiece :)
To use this app is your own risk, you have been warned :P

 

BUT:

* Converting realworld to lomac coordinates doesnt work properly.

 

I have taken the C++ math code and converted them to C#. However when executing the code to convert a value of say, 41.2314E to realworld using the GetCoords() the c# compiler replies with "Infinity":confused:.

 

The code isnt at all complicated. If you know java you can dig into c# very quickly. I know how it feels to struggle with other people's code. My code is rather legible, structred and some in-code documentation are available.

 

If i can iron out the coordinates issue then the app is nearly ready for a demo release. Oke, it wont win any beauty contests :icon_karu

 

The work continues.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

u can find a msvc project file with compiled exe in this zip file aswell as the flash .fla and .swf... simply using the code valery sent me...it`s purely procedural and doesn`t use any objects so it should compile under c aswell as c++

 

http://www.polymoon.org/tobi/privat/latlong2xz.zip

 

Hope it helps... it outputs the same coordinates as u can find in the mission files and probably scene file so it`s actually exactly what u need...

Posted

 

Grr, i get differnt results from a dotnet Managed C++ (class library project) and the code provided by Eagle Dynamics :mad:.

 

I have loaded that .dsw project into VS2003.NET and ran it. This is the output;

 

Please enter the Latitude:
44.4134
Please enter the Longitude:
33.2254
The result is:
X:-79981.273438
Z:-82053.031250

MiddleLongitude:33.000000

ToAngleW_E:1.434656

ToDegree:57.295780

lenSouth:7038538.023034

EndSouth:40.000000

ToLengthN_S:0.000009

realAng:0.002742

realLen:6545005.879861

Mal Variablen vergleichen und Wundern

 

 

Now this is the output of the exact same code, but it was converted to a dotnet C++ class library.

 

realAng = 0.13884959128047325
realLen = 6545005.7833973151
outX = -17015.813559228554
outZ = 805854.12593440851

 

WTF?!?:rolleyes:

 

 

 

 

For clarity, here is the converted dotnet class code.

// pappavislockonmapeditorKrimCoordinates.h

#pragma once
#using <mscorlib.dll>
using namespace System;

//Convert realworld coordinates to lockn Krimea coordinates.
//see this http://forum.lockon.ru/showthread.php?p=152219#post152219
//This original code courtesy of Valery Blaznov at Eagle Dynamics, http://lockon.ru
//Converted to Microsoft Dotnet on 17-jan-2006 by pappavis@hotmail.com
namespace pappavislockonmapeditorKrimCoordinates
{
public __gc class clsKrimCoordinates
{
	static const double pi = 3.14159265358979323846;

	static const float zeroX = 5000000.f; // Real coordinates beginning
	static const float zeroZ = 6600000.f;

	static const float centerX = 11465000.f - zeroX; // Circle center
	static const float centerZ = 6500000.f - zeroZ;

	static const float pn40x24_X = 4468608.57f - zeroX; // point 40dgN : 24dgE
	static const float pn40x24_Z = 5730893.72f - zeroZ;

	static const float pn48x24_X = 5357858.31f - zeroX; // point 48dgN : 24dgE
	static const float pn48x24_Z = 5828649.53f - zeroZ;

	static const float pn40x42_X = 4468608.57f - zeroX; // point 40dgN : 42dgE
	static const float pn40x42_Z = 7269106.20f - zeroZ;

	static const float pn48x42_X = 5357858.31f - zeroX; // point 48dgN : 42dgE
	static const float pn48x42_Z = 7171350.00f - zeroZ;

	static const double lenNorth = Math::Sqrt((pn48x24_X-centerX)*(pn48x24_X-centerX) + (pn48x24_Z-centerZ)*(pn48x24_Z-centerZ));
	static const double lenSouth = Math::Sqrt((pn40x24_X-centerX)*(pn40x24_X-centerX) + (pn40x24_Z-centerZ)*(pn40x24_Z-centerZ));
	static const double lenN_S = lenSouth - lenNorth;

	static const double RealAngleMaxLongitude = Math::Atan (((double)pn40x24_Z - centerZ)/(pn40x24_X - centerX)) * 180.f / pi;

	// Map bounds. Degrees!
	static const float EndWest = 24.f;
	static const float EndEast = 42.f;
	static const float EndNorth = 48.f;
	static const float EndSouth = 40.f;
	static const float MiddleLongitude = (EndWest + EndEast) / 2;

	static const float ToLengthN_S = (float)((EndNorth - EndSouth) / lenN_S);
	static const double ToAngleW_E = (MiddleLongitude - EndWest) / RealAngleMaxLongitude;
	static const double ToDegree = 180. / 	pi;

	private:
		double _outX;
		double _outZ;

	public:
		//Convert realworld to lockon internal coordinates.
		int clsKrimCoordinates::GetKrimCoords(double inLatitudeGrad, double inLongitudeGrad)
		{
			double realAng = (inLongitudeGrad - MiddleLongitude) / ToAngleW_E / ToDegree;
			double realLen = lenSouth - (inLatitudeGrad - EndSouth) / ToLengthN_S;
			_outX = centerX - realLen * Math::Cos (realAng);
			_outZ = centerZ + realLen * Math::Sin (realAng);

			return 1;
		}

		double outX()
		{
			return _outX;
		}

		double outZ()
		{
			return _outZ;
		}
};
}

 

 

Any idea what is wrong? Where have i gone wrong?:confused:

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

sry... looking at your dot.net code i have no idea what is going on... Of course i can see something but the devil hides in the details... obviously your

 

realLen = lenSouth - (inLatitudeGrad - EndSouth) / ToLengthN_S;

 

is correct :)

 

but your

 

realAng = (inLongitudeGrad - MiddleLongitude) / ToAngleW_E / ToDegree;

 

is not :(

 

so you should debug it step for step and find the wrong input... That's all I can say...

 

good luck

 

Edit:

 

Actually I was also nearly biting my teeth out on this code... But then again compared to the real UTM conversion it's really simple... The work will be worth it when you get the first version running...

Posted

 

realAng = (inLongitudeGrad - MiddleLongitude) / ToAngleW_E / ToDegree;

 

is not :(

 

 

 

Err, the dotnet code is copied from the example in latlong2xz.zip :confused:.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

  • 2 weeks later...
Posted

I think this might illuminate the problem:

 

           const float numA  = 4468608.57f;
           const double numB = 4468608.57f;
           const double numC = 4468608.57;
           
           System.Windows.Forms.MessageBox.Show(numA.ToString());
           System.Windows.Forms.MessageBox.Show(numB.ToString());
           System.Windows.Forms.MessageBox.Show(numC.ToString());

 

There are probably differences between floats in C++ and C#.

 

Cheers,

LP

LP

 

modules:

F5-E / A4-E / A-10A / AJS-37 / SA-342 / UH-1H / Ka-50 / Mi-8 / CA

 

would buy:

OH-58 /AH-64A / AH-1 / Sepecat Jaguar / F-111

Posted

yep so i have noticed, there is a minor but definite difference. After having seen this difference in values between managed C++ and unmanaged C++ there is uncertainty about the accuracy of c++ maths values.

Not that i ever intent on using C++.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

The inconsistency is probably just due to differences in precision of the floating point datatypes. I recommend using double (without the 'f' appended), and round to 3 decimals after each multiplication/division.

 

Good luck with your project, it sounds cool. Let me know if I can help with anything.

 

Cheers,

LP

LP

 

modules:

F5-E / A4-E / A-10A / AJS-37 / SA-342 / UH-1H / Ka-50 / Mi-8 / CA

 

would buy:

OH-58 /AH-64A / AH-1 / Sepecat Jaguar / F-111

Posted

Yes sure thanks.

 

I made some new code, it seems that lockon doesnt grasp the file created by me, there are minor differences in the header bytes.

 

I have had a look in a binary editor and sees that the first 1535 bytes makes a header of a mission file. Some byte are changed in that header. I suspect it to do with encoding, in some way or another.

 

See attached code to convert XML from a mission to a real .mis file' bytes.

 

I made these code to:

* read a example misison file ("Su-25 Night Strike.mis") as binary.

* Get the first 1535 as binary header.

* Get the XML from a mission file such as "Su-25 Night Strike.mis".

* Append XML from a mission file to the header.

* Return a byte array, to write to file using a System.IO.Binarywriter.

 

Prob is the first 1535 bytes of the output bytes are not equal to "Su-25 Night Strike.mis". Any ideas?

 

		#region Converts the XML missionfile to MIS.
	/// <summary>
	/// Converts the XML to lockon internal' MIS-fileformat.
	/// </summary>
	/// <param name="xDocToConvert">The xml missionfile source to convert.</param>
	/// <returns></returns>
	public byte[] GetXMLtoMIS(XmlDocument xDocToConvert)
	{
		byte[] bytMissionHeader = null;
		byte[] bytResult = null;

		try
		{
			string strBaseMissionName = AppDomain.CurrentDomain.BaseDirectory + @".\" + ConfigurationSettings.AppSettings["LockonMissionHeader"];
			FileStream fs = new FileStream(strBaseMissionName, FileMode.Open);
			BinaryReader brInput1 = new BinaryReader(fs);

			//Open die voorbeeld lockon .mis-bestand, zoek naar <Lockon en vervangen met eigen misison XML.
			if(brInput1 != null)
			{
				bytMissionHeader = brInput1.ReadBytes(Convert.ToInt32(brInput1.BaseStream.Length));
				int intMissionHeaderEndpos = int.Parse(ConfigurationSettings.AppSettings["MissionHeaderEndpos"]);
				byte[] bytMissionXML = Encoding.UTF8.GetBytes(xDocToConvert.OuterXml.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""));

				//Recerveer een deel van geheugen, hier gaat de mission file tijdelijk in worden aangemaakt.
				byte[] bytTemp1 = new byte[intMissionHeaderEndpos + bytMissionXML.Length];

				//kopieer mission header definite, van Eagle Dynamics.
				for(int intTeller = 0; intTeller < intMissionHeaderEndpos; intTeller++)
				{
					bytTemp1[intTeller] = bytMissionHeader[intTeller];
				}

				//Plak de nieuwe door gebruiker gemaakt XML achter aan die header van ED missionfile.
				int tel2 = 0;
				for(int intTeller = intMissionHeaderEndpos + 1; intTeller < intMissionHeaderEndpos + bytMissionXML.Length; intTeller++)
				{
					bytTemp1[intTeller] = bytMissionXML[tel2];
					tel2++;
				}

				bytResult = bytTemp1;
			}
		}
		catch(Exception ex)
		{
			throw new Exception(ex.Message + "; " + ex.StackTrace);
		}

		return bytResult;
	}
	#endregion

 

 

This code writes a .mis file:

public void WriteMISfile()
{
		try
		{
			byte[] bytMIS = new clsMissionFile().GetXMLtoMIS(_xDocNewMission1);

			FileStream fs = new FileStream(objSaveMap.Filename, FileMode.OpenOrCreate);
			BinaryWriter bwOutMIS = new BinaryWriter(fs);

			if(bwOutMIS != null)
			{
				for(int intMisPos = 0 ; intMisPos < bytMIS.Length; intMisPos++)
				{
					bwOutMIS.Write(bytMIS[intMisPos]);
				}
				bwOutMIS.Close();
			}
		}
		catch(Exception ex)
		{
			MessageBox.Show("Error: " + ex.Message + "; " + ex.StackTrace, _appNaam,  MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
		}

}

PM me then i'll send you the complete source code, all about 1.8mb.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

I wrote a similar tool before (in Perl), and I think the mission header is actually 1536 chars. (0-1535)

I am assuming that this code is returning 1535?:

 ConfigurationSettings.AppSettings["MissionHeaderEndpos"]

I did a test with this assumption, and noticed that

the final '>' character was missing from the end of the file.

 

What I had to do, was add 1 to the output array:

 byte[] bytTemp1 = new byte[intMissionHeaderEndpos + bytMissionXML.Length + 1];

and change your loop to catch the final char (<=):

 for(int intTeller = intMissionHeaderEndpos + 1; intTeller <= (intMissionHeaderEndpos + bytMissionXML.Length); intTeller++)

Basically just an "off-by-one" issue.

 

 

I tested it, and I can load the mission in the editor.

 

Hope this helps.

 

Cheers,

LP

 

LP

 

modules:

F5-E / A4-E / A-10A / AJS-37 / SA-342 / UH-1H / Ka-50 / Mi-8 / CA

 

would buy:

OH-58 /AH-64A / AH-1 / Sepecat Jaguar / F-111

Posted

hoi lazer, Thanx 4 your help :))

 

Yes, i assumed the header file length to be 1535 bytes. This code

ConfigurationSettings.AppSettings["MissionHeaderEndpos"]

is a config variable which is te size of the header in chars. I have changed it to 1546 bytes. Gonna try these new setting at home tonight. My boss wont like it if i do lo-mac stuff here at work :P.

 

Does ASCII/UTF-8 encoding have a role to play in this conversion?

 

Coz what i do is:

* read the "Su-25 Night Strike.mis" into a byte array, default dotnet encoding.

* Copy the first 1536 bytes from "Su-25 Night Strike.mis" into a byte array.

* Append misison XML (which is everything past byte 1536) to byte array.

* Write this byte array out to file.

 

Thought the file seems perfect when visually observed using the VS.NET2003 hex editor, there are some minor differrnces. Some bytes have differnt values. Possibly due to a ASCII/UTF-8 encoding thingy in VS2003??

 

Anyways, gonna try it tonight at home.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

How's it going? Did you get it loading your mission in the editor yet?

 

I don't think encoding is an issue, since I got it working with VS2003 and C# Express. I took an existing mission xml file, ran it through the program and it created the .mis file. I opened the .mis file in the LOMAC editor, and it didn't complain.

 

Let me know if you want a copy of my code.

 

Cheers,

LP

LP

 

modules:

F5-E / A4-E / A-10A / AJS-37 / SA-342 / UH-1H / Ka-50 / Mi-8 / CA

 

would buy:

OH-58 /AH-64A / AH-1 / Sepecat Jaguar / F-111

Posted

Since I'm really busy doing other uninteresting stuff I might aswell add my java code to split mission files into header and Xml and join them back together again...

 

 

To Split:

 


import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.*;


public class Chooser extends JPanel {
	public File selection = null;
	JFileChooser fc;

public Chooser() {
	fc = new JFileChooser();
	int returnVal = fc.showOpenDialog(Chooser.this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
               selection = fc.getSelectedFile();
               //This is where a real application would open the file.
               System.out.print("Opening: " + selection.getName() + "." + "\n");
			ReadMission(selection);
		} else {
			System.exit(0);
		}
}

public void ReadMission (File r3) {
	
	try {
		BufferedReader r2;
		BufferedWriter w2;
		BufferedWriter w3;
		char charBuffer[] = new char[1];
		StringBuffer stringBuffer = new StringBuffer(16777216);
		int Begin;
		r2 = new BufferedReader(new FileReader(r3));
		
	
	while (r2.read(charBuffer,0,1) != -1) {
		//System.out.print((char)charBuffer[0]);
		stringBuffer.append(charBuffer[0]);
	}
		r2.close();
		Begin = stringBuffer.toString().indexOf("<LockOn_Mission"); 
		
		if(Begin != -1){
			w2 = new BufferedWriter(new FileWriter("./mission.xml"));
			String MissionXML = new String(stringBuffer);
			String MissionXML2 = MissionXML.substring(Begin);
			String MissionHeader = MissionXML.substring(0, Begin);
			//System.out.print(MissionXML2);
			w2.write(MissionXML2);
			w2.close();
			w3 = new BufferedWriter(new FileWriter("./header.ukn"));
			w3.write(MissionHeader);
			w3.close();				
			System.out.print("Finished extracting XML and Header" + "\n");
		} else {
			System.out.print(selection.getName() + " is not a Mission File" + "\n");
			System.exit(0);
		}
		
	} catch (IOException e) {
		System.out.println("Fehler beim Lesen der Datei");
	}
	System.exit(0);
}

public static void main (String args[]) {
	JComponent newContentPane = new Chooser();
       newContentPane.setOpaque(true); //content panes must be opaque
}
}

 

 

To Join:

 

import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.*;


public class Saver extends JPanel {
	public File selection = null;
	JFileChooser fc;

public Saver() {
	fc = new JFileChooser();
	int returnVal = fc.showSaveDialog(Saver.this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			selection = fc.getSelectedFile();
			//This is where a real application would open the file.
               System.out.print("Saving: " + selection.getName() + "." + "\n");
			SaveMission(selection);
		} else {
			System.exit(0);
		}
}

public void SaveMission (File r3) {
	
	try {
		BufferedReader r2;
		BufferedReader r4;
		BufferedWriter w3;
		char charBuffer[] = new char[1];
		
		StringBuffer stringBuffer2 = new StringBuffer(16777216);
		
		r2 = new BufferedReader(new FileReader("./header.ukn"));
		r4 = new BufferedReader(new FileReader("./mission.xml"));
	
	while (r2.read(charBuffer,0,1) != -1) {
		//System.out.print((char)charBuffer[0]);
		stringBuffer2.append(charBuffer[0]);
	}
		r2.close();
	while (r4.read(charBuffer,0,1) != -1) {
		//System.out.print((char)charBuffer[0]);
		stringBuffer2.append(charBuffer[0]);
	}
		r4.close();			
		
			w3 = new BufferedWriter(new FileWriter(r3));
			w3.write(stringBuffer2.toString());
			w3.close();
			System.out.print("Finished saving "+r3+"\n");
			System.exit(0);
		
	} catch (IOException e) {
		System.out.println("Fehler beim Lesen der Datei");
	}
	System.exit(0);
}

public static void main (String args[]) {
	JComponent newContentPane = new Saver();
       newContentPane.setOpaque(true); //content panes must be opaque
}
}

Posted
How's it going? Did you get it loading your mission in the editor yet?

 

Let me know if you want a copy of my code.

 

Cheers,

LP

 

Yes, sure please send.

met vriendelijke groet,

Михель

 

"умный, спортсмен, комсомолетс"

 

[sIGPIC]159th_pappavis.jpg[/sIGPIC]

 

[TABLE]SPECS: i9-9900K 32gigs RAM, Geforce 2070RTX, Creative XFi Fata1ity, TIR5, Valve Index & HP Reverb, HOTAS Warthog, Logitech G933 Headset, 10Tb storage.[/TABLE]

Posted

Hi guys,

I am hopeful that someone will create a compiler/de-compiler utility for the .lsa2 file. Bazar>Terrain>Surface>High>land.lsa2

This file contains pointers to land tetures. I believe it also contains elevation and map coordinate data.

Any help with this would be much appreciated.

Dave "Hawg11" St. Jean

Posted

Hi pappavis,

 

Here is what I was playing with. It's based on your code, but I hardcoded some filenames. PM me if anything is unclear.

 

 

       XmlDocument _xDocNewMission1 = new XmlDocument();

       private void Form1_Load(object sender, EventArgs e)
       {

           _xDocNewMission1.Load(AppDomain.CurrentDomain.BaseDirectory + @".\" + "mission_template.xml");
           WriteMISfile();
           
       }

 

       #region Converts the XML missionfile to MIS.
       /// <summary>
       /// Converts the XML to lockon internal' MIS-fileformat.
       /// </summary>
       /// <param name="xDocToConvert">The xml missionfile source to convert.</param>
       /// <returns></returns>
       public byte[] GetXMLtoMIS(XmlDocument xDocToConvert)
       {
           byte[] bytMissionHeader = null;
           byte[] bytResult = null;

           try
           {
               string strBaseMissionName = AppDomain.CurrentDomain.BaseDirectory + @".\" + "lomac_header.bin";
               FileStream fs = new FileStream(strBaseMissionName, FileMode.Open);
               BinaryReader brInput1 = new BinaryReader(fs);

               //Open die voorbeeld lockon .mis-bestand, zoek naar <Lockon en vervangen met eigen misison XML.
               if(brInput1 != null)
               {
                   bytMissionHeader = brInput1.ReadBytes(Convert.ToInt32(brInput1.BaseStream.Length));
                   int intMissionHeaderEndpos = 1535;
                   byte[] bytMissionXML = Encoding.UTF8.GetBytes(xDocToConvert.OuterXml.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""));

                   //Recerveer een deel van geheugen, hier gaat de mission file tijdelijk in worden aangemaakt.
                   byte[] bytTemp1 = new byte[intMissionHeaderEndpos + bytMissionXML.Length + 1];

                   //kopieer mission header definite, van Eagle Dynamics.
                   for(int intTeller = 0; intTeller < intMissionHeaderEndpos; intTeller++)
                   {
                       bytTemp1[intTeller] = bytMissionHeader[intTeller];
                   }

                   //Plak de nieuwe door gebruiker gemaakt XML achter aan die header van ED missionfile.
                   int tel2 = 0;
                   // LP NEW - change to <=, to not miss last '>' char
                   for(int intTeller = intMissionHeaderEndpos + 1; intTeller <= (intMissionHeaderEndpos + bytMissionXML.Length); intTeller++)
                   {
                       bytTemp1[intTeller] = bytMissionXML[tel2];
                       tel2++;
                   }

                   bytResult = bytTemp1;
               }
           }
           catch(Exception ex)
           {
               throw new Exception(ex.Message + "; " + ex.StackTrace);
           }

           return bytResult;
       }
       #endregion

       public void WriteMISfile()
       {
           try
           {
               byte[] bytMIS = GetXMLtoMIS(_xDocNewMission1);

               FileStream fs = new FileStream("C:\\test.mis", FileMode.OpenOrCreate);
               BinaryWriter bwOutMIS = new BinaryWriter(fs);

               if(bwOutMIS != null)
               {
                   for(int intMisPos = 0; intMisPos < bytMIS.Length; intMisPos++)
                   {
                       bwOutMIS.Write(bytMIS[intMisPos]);
                   }
                   bwOutMIS.Close();
               }
           }
           catch(Exception ex)
           {
               MessageBox.Show("Error: " + ex.Message + "; " + ex.StackTrace);
           }
       }

 

Cheers,

LP

LP

 

modules:

F5-E / A4-E / A-10A / AJS-37 / SA-342 / UH-1H / Ka-50 / Mi-8 / CA

 

would buy:

OH-58 /AH-64A / AH-1 / Sepecat Jaguar / F-111

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...