Jump to content
Sign in to follow this  
celery

CLY Morse - a Morse code encoder/decoder and player

Recommended Posts

cly_morse.png

Here's a script that encodes plain text into Morse and vice versa, and plays the sounds too.

>Download mission<

Encode a text:

morsestring=["Encode"] call CLY_morse;

hintSilent format ["%1",morsestring];

Decode a Morse transmission:

morsestring=["-.. . -.-. --- -.. ."] call CLY_morse;

hintSilent format ["%1",morsestring];

Play Morse code sound:

morsestring=["This should play a sound.",objNull,2] call CLY_morse;

Finer details are explained in cly_morse.sqf. :)

.... .- .--. .--. -.--   -- --- .-. ... .. -. --. -.-.--

Changelog:

June 14 2011

- Optimized code

- Fixed 1 dot too long word space

- Script now encodes Cyrillic alphabet (cut and paste the section above Latin if you need to decode into Cyrillic)

Here are the scripts in plain code:

init.sqf

CLY_morse=compile preprocessFile "cly_morse.sqf";

description.ext

class CfgSounds
{
class dash
{
	name="dash";
	sound[]={\sound\dash.ogg,0.04,2}; //Change speed (last element) to match your call argument!
	titles[]={};
};
class dot
{
	name="dot";
	sound[]={\sound\dot.ogg,0.04,2}; //As above
	titles[]={};
};
};

cly_morse.sqf

/*
CLY Morse - a Morse code encoder/decoder and player
Author: Celery
Version: June 14 2011

-How to use-
1) Put this line in your init script:
	CLY_morse=compile preprocessFile "cly_morse.sqf";
2) Use the CfgSound entries in the test mission's description.ext.
3) Put the test mission's sounds into your mission folder.
4) Call CLY_morse in a trigger or script:
	morsestring=["I am using Morse code",objNull,2] call CLY_morse;
	^return string    ^input   sound source^     ^speed

The return string will have the converted text/code that you can use for text output elsewhere.

The input is either normal text that you want to decode into Morse, or pure Morse code (".", "-", " " only) that you want to decode.
When writing Morse, " " is a letter space and "   " is a word space.

The sound source can be an object that generates the sound, or objNull in which case you will hear the code inside your head.
Speed is 0.1 seconds divided by X per dot. For best results, change the description.ext CfgSound speeds accordingly.
If you don't need sound, write only the input into the argument array.
*/

private ["_morsecodes","_string","_object","_speed","_encode","_stringarray","_morsestring"];

_morsecodes=[
["Aa",".-"],
["Bb","-..."],
["Cc","-.-."],
["Dd","-.."],
["Ee","."],
["Ff","..-."],
["Gg","--."],
["Hh","...."],
["Ii",".."],
["Jj",".---"],
["Kk","-.-"],
["Ll",".-.."],
["Mm","--"],
["Nn","-."],
["Oo","---"],
["Pp",".--."],
["Qq","--.-"],
["Rr",".-."],
["Ss","..."],
["Tt","-"],
["Uu","..-"],
["Vv","...-"],
["Ww",".--"],
["Xx","-..-"],
["Yy","-.--"],
["Zz","--.."],
["0","-----"],
["1",".----"],
["2","..---"],
["3","...--"],
["4","....-"],
["5","....."],
["6","-...."],
["7","--..."],
["8","---.."],
["9","----."],
[" "," "],
[".",".-.-.-"],
[",","--..--"],
[":","---..."],
[";","-.-.-."],
["?","..--.."],
["!","-.-.--"],
["'",".----."],
["""",".-..-."],
["=","-...-"],
["+",".-.-."],
["-","-....-"],
["_","..--.-"],
["/","-..-."],
["(","-.--."],
[")","-.--.-"],
["&",".-..."],
["@",".--.-."],
["$","...-..-"],
[[196,228,198,230],".-.-"], //"ÄäÆæ"
[[197,229,193,225,192,224],".--.-"], //"Ã…Ã¥ÃáÀà"
[[199,231],"-.-.."], //"Çç"
[[208,240],"..--."], //"Ãð"
[[201,233],"..-.."], //"Éé"
[[200,232],".-..-"], //"Èè"
[[209,241],"--.--"], //"Ññ"
[[214,246,216,248,211,243],"---."], //"ÖöØøÓó"
[[222,254],".--.."], //"Þþ"
[[220,252],"..--"], //"Üü"
//Cyrillic alphabet
[[1040,1072],".-"],
[[1041,1073],"-..."],
[[1042,1074],".--"],
[[1043,1075],"--."],
[[1044,1076],"-.."],
[[1045,1077,1025,1105],"."],
[[1046,1078],"...-"],
[[1047,1079],"--.."],
[[1048,1080],".."],
[[1049,1081],".---"],
[[1050,1082],"-.-"],
[[1051,1083],".-.."],
[[1052,1084],"--"],
[[1053,1085],"-."],
[[1054,1086],"---"],
[[1055,1087],".--."],
[[1056,1088],".-."],
[[1057,1089],"..."],
[[1058,1090],"-"],
[[1059,1091],"..-"],
[[1060,1092],"..-."],
[[1061,1093],"...."],
[[1062,1094],"-.-."],
[[1063,1095],"---."],
[[1064,1096],"----"],
[[1065,1097],"--.-"],
[[1066,1098],"--.--"],
[[1067,1099],"-.--"],
[[1068,1100,1066,1098],"-..-"],
[[1069,1101],"..-.."],
[[1070,1102],"..--"],
[[1071,1103],".-.-"]
];

_string=_this select 0;
_object=if (count _this>1) then {_this select 1} else {nil};
_speed=if (count _this>2) then {_this select 2} else {1};
_encode={!(_x in [32,45,46])} count toArray _string>0;
_stringarray=[];
_morsestring="";

if (_encode) then {
//Encode
{
	_char=_x;
	_codefound=false;
	{
		_chars=_x select 0;
		if (typeName _chars=="STRING") then {
			_chars=toArray _chars;
		};
		if (_char in _chars and !_codefound) then {
			_stringarray set [count _stringarray,_x select 1];
			_codefound=true;
		};
	} forEach _morsecodes;
} forEach toArray _string;
//Form Morse code string
{
	_space=if (_forEachIndex>0) then {" "} else {""};
	_morsestring=_morsestring+_space+_x;
} forEach _stringarray;
} else {
//Decode
_morsestring=_string;
_char=[];
_space=[];
{
	if (_x!=32) then {
		_char set [count _char,_x];
		_space=[];
		if (_forEachIndex+1==count toArray _string) then {
			_stringarray set [count _stringarray,toString _char];
			_char=[];
		};
	};
	if (_x==32) then {
		if (count _space==0) then {
			_stringarray set [count _stringarray,toString _char];
		};
		_char=[];
		_space set [count _space,_x];
		if (count _space==3) then {
			_stringarray set [count _stringarray," "];
		};
	};
} forEach toArray _string;
//Translate morse to humanspeak
_string="";
{
	_char=_x;
	_codefound=false;
	{
		if (_char==(_x select 1) and !_codefound) then {
			_letters=_x select 0;
			if (typeName _letters=="STRING") then {
				_letters=toArray _letters;
			};
			_string=_string+toString [_letters select 0];
			_codefound=true;
		};
	} forEach _morsecodes;
} forEach _stringarray;
};

//Play sound
if (!isNil "_object") then {
[_object,_morsestring,_speed] spawn {
	_object=_this select 0;
	_morsestring=_this select 1;
	_speed=_this select 2;
	if (_speed<=0) then {_speed=1};
	_soundarray=toArray _morsestring;
	_space=[];
	{
		_wait=0.1;
		_sound="";
		if (_x==32) then {
			_space set [count _space,_x];
			if (count _space==3) then {
				_wait=0;
				_space=[];
			};
		};
		if (_x==45) then {
			_sound="dash";
			_wait=0.3;
			_space=[];
		};
		if (_x==46) then {
			_sound="dot";
			_wait=0.1;
			_space=[];
		};
		if (_sound!="") then {
			if (!isNull _object) then {
				_object say3D _sound;
			} else {
				playSound _sound;
			};
		};
		sleep (_wait/_speed);
		sleep (0.1/_speed);
	} forEach _soundarray;
};
};

//Return string
if (_encode) then {_morsestring} else {_string};

Edited by Celery

Share this post


Link to post
Share on other sites

A very, very interesting usage for Arma 2's engine!

Theoretically could be used for non-Arma related work, but the script might come in more handy in some WW2 missions. Greatly adds to the atmosphere of cut-scenes I believe.

Oh, and while taking a brief look at the script I noticed that you forgot to "privatize" local variables. Never hurts.

private ["_string","_object","_speed","_encode","_stringarray","_morsestring"];

Share this post


Link to post
Share on other sites
Oh, and while taking a brief look at the script I noticed that you forgot to "privatize" local variables. Never hurts.

Updated.

Share this post


Link to post
Share on other sites

Morse code should have been already in the game. Also, I think that most morse coders will agree with me.

(This should become a meme)

Share this post


Link to post
Share on other sites

Too cool! Being an amateur radio operator I'm pretty familiar with CW aka Morse Code. I often wondered during multiplayer while playing with the ACRE radio mod how hard it would be to integrate CW into the ACRE Radio System. For those who aren't familiar with CW, the mode of CW can very easily be heard when voice transmissions using the same output power and antenna can not.

Super cool addon.

Share this post


Link to post
Share on other sites

Is there an all-encompassing Morse chart anywhere on the intertubes? I'd like to add all possible special characters and letters that have a morse code into the script's conversion array.

Share this post


Link to post
Share on other sites

well, wiki has a few here: and more example in links at bottom of page.

cool release btw.

Share this post


Link to post
Share on other sites

Morse alphabet in:

  • Greek
  • Cyrillic
  • Hebrew
  • Arabic
  • Farsi
  • Japanese
  • Chinese

Link

Share this post


Link to post
Share on other sites

Yeah, I did the array based on the Wiki page, but I had to hunt down some individual characters elsewhere.

Share this post


Link to post
Share on other sites

Very cool Celery. I was just posting in the ACRE thread about electronic warfare on today's comms. The BEST way if being jammed is to burn through it using morse code !

Share this post


Link to post
Share on other sites

Script updated

New version and changelog in first post.

Share this post


Link to post
Share on other sites

That is wicked. Do you reckon you can do the same for a manned searchlight - preferably with three speeds (normal, slow, slowest)? If so, come more sophisticated handling of ships, you will have accommodated for fantastic naval gameplay.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×