April 2015 update of “Ini++ v1.5”

The Multimedia Fusion v2.5 extension manager now contains the April 2015 version of Ini++ v1.5. This is a small update that fixes a problem with one of the expressions.

This version is only available from the extension manager. My website no longer contains the latest version.

The description text for the latest version ends with the words “April 2015 build”, as shown below:

Extention manager

String Replace object updated

I’ve updated the String Replace extension for Multimedia Fusion in order to support a new action that clears the list of rules.

I did look at updating the extension to support Unicode and properly support the Unicode version of Multimedia Fusion (which includes the new Fusion 2.5). However, the SDK I was using is too out of date and so it would’ve been quite a lot of effort. Therefore the object does not support Unicode and also the array and global string functionality does not work in Fusion 2.5 or the Unicode version of Multimedia Fusion 2.

When the Fusion 2.5 SDK is released I may look at rewriting the object (in a compatible manner) so that it does support Unicode, and also perhaps get it to work on other platforms. I’m not sure yet, but it seems like it’d be a good way to get back into extension development for a possible future Ini++ Lite object. I have mentioned this idea in a previous post on this blog.

Download

New version of Ini++ fixes crash

I have updated the Multimedia Fusion 2 extension Ini++. The update fixes a crash. This crash only occurred when both encryption and disk access were enabled, as far as I know. This build hopefully fixes the problem. It is referred to as the October 2013 build (sorry for it taking until mid-November to release it!)

Thank you to Logan Apple for his extremely useful help in reproducing this problem.

Update: It was reported that Build 258.2 and higher of Multimedia Fusion breaks this extension. I could not reproduce this and it appears to work fine in Fusion 2.5.

Download Link

MMX Instructions

In 1997 Intel added a set of instructions to their Pentium processor that were expected to be useful for audio and image processing. This was called MMX. The major feature it allowed was the adding of four 16-bit variables in one instruction (or alternatively eight 8-bit values or two 32-bit values).

It also features a mode where the value of the addition  ‘saturates’ rather than wraps. For instance, 100+200 = 255 using unsigned 8-bit saturation arithmetic. This is particularly useful in image and audio processing as wrapping often does not make sense in these cases. For instance, suppose we have a bitmap image where, after a header, every value is stored as 3 bytes in a row. Suppose we wish to make the image a bit lighter. It is simple to achieve this, as shown below.

// Assume 'data' is a character array holding the bitmap data, excluding
// the header. len holds the length of this array.
for ( int pos = 0 ; pos != len ; ++pos )
{
 int newValue = data[pos] + 50;
 if ( newValue < 0 )
   newValue = 0;
 if ( newValue > 255 )
   newValue = 255;
 data[pos] = newValue;
}

If I run this on my test image (which contains 844,048 pixels) it takes about 3.1ms, excluding the time to read to and write from file.

I wondered how much faster it would be using the MMX byte-wise saturated adding function. I shall be using the MSVC compiler and so MASM style inline assembly will be used. The instruction required is paddusb. The first parameter is a MMX register and the second location is either a MMX register or a memory location. The result is written to the first parameter.

So the basic idea is that we loop ‘data’, send the current 8-bytes chunk into an MMX register, call the saturated add function and then put the resulting variable back into the memory location we found it in. This gives us something like this:

unsigned char* end = data + len;
unsigned char toAdd[] = {50,50,50,50,50,50,50,50};
while ( data < end )
{
   __asm mov eax,data
   __asm movq MM0,[eax]
   __asm paddusb MM0,toAdd
   __asm movq [eax],MM0
  data += 8;
}
__asm emms // Restore state
// If data != end the last few should be adjusted without
// the use of these special instructions. I won't do this
// for demo purposes

Note that the ’emms’ instructed is required after we have finished with MMX, as otherwise floating point calculations won’t work properly (MMX and the floating point instructions use the same registers). ‘movq’ accepts a memory address as the second parameter, so we use the location that ‘data’ is pointing to. (We have to dereference it and so it must be in a register. It is not allowed to have an instruction like ‘movq MM0,[data]‘)

The same example now runs in 0.4ms – nearly 8 times faster.

Finally, we can optimise this a little. We are using ‘data’ as a counter and then keep transferring it to ‘eax’. Why not just use ‘eax’ directly? Finally, since we are not short on registers, we should make sure that ‘toAdd’ is always in a register. Let’s leave it in MM1. This gives us the following final code:

__asm
{
 // eax will contain the current offset
 mov eax, data
 // ebx will contain the final offset
 mov ebx, data
 add ebx, len
 // MM1 contains the constant to add
 movq MM1,toAdd
TOP:
    // load in the value to MM0
    movq MM0,[eax]
    paddusb MM0,toAdd
    movq [eax],MM0
    add eax,8
    cmp eax,ebx
    jl TOP
  // Again, deal with remaining bits here
  // for real production code
  emms
}

It now runs in 0.3ms – over 10 times faster than the original version.

Nothing clever was done here – just some (now) standard instructions were used in the most basic and standard way. However, the increased speed was incredible and so I thought I would share it.

Update to Ini++ v1.5 and thoughts about a new extension

I have issued an update to Ini++ v1.5. It fixes a couple of memory leaks do with the undo stack. The memory leak applied even if the undo stack was disabled. For this reason it is important that every user update to the latest version.

In addition, a minor bug is fixed where the undo and redo stack size could be set to 128 layers. This would actually register as infinite. Now the properties panel will not allow any values greater than 127. If you previously choose 128 it will stay selected, so you ought to be aware of this.

There are still known bugs. I have been able to reproduce a crash with the encryption. Hopefully I’ll  be able to fix this in future, but I do not have the tools available to do so quickly. I apologise for the instability. Thank you to HitmanN and XStar for sending me examples of these problems.

The new version can be downloaded here.    It has since been updated again, see here.

In addition, I wanted to float a new idea. Many people have asked for Ini++ to be ported to other platforms. This will not happen. Ini++ is a monster of an object with many, many features. One only has to look at the file size and options to realise this. Therefore it would be a lot of effort to port to any other platform.

There is a demand for a data storage object on other platforms though, and it seems the format of Ini++ is one that appeals to people. Therefore I propose a cut-down version of Ini++ be created and ported to every platform. This is obviously a fairly big project for me to undertake, and I’m not sure yet that I want to do this. But I wanted to ask people what features are important to them.

Some of the features that Ini++ support are:

  • Compression
  • Encryption
  • Built in features to save the file in specific directories
  • Setting initial data
  • Debugging tools, including a dialog that can be opened at runtime
  • Case sensitive/insensitive options (including the ability to change it at runtime)
  • Repeated groups and items via renaming
  • The ordering of the file is preserved (but comments, etc. are not)
  • Options to auto-save or not
  • Searching features
  • Sorting and reordering features
  • Merging functions
  • Half-baked ‘subgroups’
  • Global data, including across sub-apps. (Is the latter even possible in other runtimes?)
  • Hashed values
  • Get/Set as text, CVS
  • Listing groups and items
  • ‘Perform calculation’ expressions that allows summary information to be easily extracted. Has anybody ever used that?
  • Undo and redo stacks
  • Escape characters
  • Alphanum sorting that puts, say, “Hello 12” before “Hello 3”
  • Interaction with the chart object, array object
  • Functions to get the ‘part’ of a string directly
  • Lots of actions had custom dialog boxes in MMF
  • Saving objects and global values directly
  • Ability to allow/disallow empty groups, etc.
  • ‘Current group’ set of features

Some extra features I was going to add were: Filtering of the object (so that it would changes what the object lists and so forth without actually changing the object), proper subgroups, saving to formats other than Ini files (in particular, making the whole thing work the same but write to the registry or via a server) and full preservation of white space, etc. Unicode support everywhere would be good, too. Encryption is memory was an idea too, but it is questionable how useful that is.

Which features are the most important? If people could tell me (on the Clickteam Forums) their top 5 or so features in order I would find it very useful. Remember, it would take too long to add every feature to every platform, so be conservative.

Preprocessor Programming (All 9 parts as a PDF)

The recent series of articles about Preprocessor (Meta-)Programming is now available as a PDF file. Hopefully it is easier to read like this. It is about writing code which is evaluated with the C preprocessor.

preprocessor_preview

Click to view/download

The original posts have now been removed from the blog as they are all included in this one.

Chart Object now can be added to MMF HWA applications

The Chart Object I wrote for Multimedia Fusion 2 would not allow itself to be added to hardware accelerated (HWA) applications. At the time the object was released, this was a separate runtime. It was disallowed as it didn’t appear to work properly with it – nothing would be displayed (except for the pie chart mode, which writes to an internal buffer first).

Today I started work to make the Chart Object HWA compatible (although not actually take advantage of the HWA). The first thing I did was remove the tests which stopped it being added to HWA applications. I tried it, and it seemed to ‘just work’ so long as the ‘Display Mode’ setting in the application properties is not ‘Direct3D 8’ or ‘Direct3D 9’ (both of which may cause crashes).

Well, I thought this would probably do for now. I’d be interested to know if there are any people who are strongly bothered by the inability to use it with Direct3D. Perhaps if it is an actual problems I will convert it to use off-screen buffers, but I’d prefer not to.

Download the version of Chart Object without the HWA checks

Edit: A quote I found from my notes from Fimbul which – probably fairly – describes the situation:

[T]he graph object. It’s great, but it’ll probably never see HWA, java, etc. It has an excellent function that allows you to get the coordinates for the points, so if you want, you can plot a graph yourself, but you can’t use that in the other runtimes (and I think it glitches even in HWA if you try to use it there). This is another example of something that is already using a form of coding, but that instead of being “click-friendly”, it’s mostly “click-impossible”.

Alas, it was created before alternative run-times, but released at about the same time as them.

Work on Multimedia Fusion extensions

A few of my extensions have known problems with it. I don’t particularly enjoy working on these projects; actually, I pretty much hate it. I have much better things I could be doing. However,  I will try to make the changes when I can.

The known problems are:

Chart Object
  • No support for HWA, which means it doesn’t work in the latest version of MMF
  • No support for Unicode titles, etc.
Ini++
  • Crash to do with encryption
String Replacer
  • Suspected crash turned out to be due to a different object
Spell check Object
  • Lack of support for additional characters (such as accented characters)
String Replacer
  • Lack of support for additional characters (such as accented characters)

None of these will be much fun at all to work on, or particularly rewarding, so don’t expect progress to be quick. However, hopefully it will happen someday.

Why so many versions of Ini++?

It is often asked why there are so many versions of the Ini++ object. I’ve explained the answer a few times on the Clickteam forums, but I thought it would be worth while explaining it here too.

The answer is: There aren’t.

The situation is that there are two versions of the Ini++ object. The original, and Ini++ v1.5. The latter was made when the Ini++ object behaviour changed. In particular, it no longer enforced items and groups to be in sorted order. Therefore I could not release this as an update to the original, as it could break peoples code. To make things worse, this was not something which could be an option either (without some rewriting of code in the original). It was called Ini++ v1.5 as a nod to Multimedia Fusion v1.5, which was Multimedia Fusion v1.0 plus many new features.

Naturally, there have been different releases of the ‘Ini++ Object’ and the ‘Ini++ v1.5’ objects, but both kept calling themselves that name. There is no ‘Ini++ v1.6’ object. There is no  ‘Ini++ v1.1’. Just the two mentioned. They have the file names ‘Ini++.mfx’ and ‘Ini++15.mfx’ respectively.

So why the confusion?

The problem stems from the fact that although the behaviour of Ini++ v1.5 changed from that of the original, it was still compatible with the original Ini++ object. That is, if you took ‘Ini++15.mfx’ and renamed it to ‘Ini++.mfx’, then any MMF application using the old version would suddenly be ‘upgraded’ to the new version. If you knew your program wasn’t going to stop working because of the changes, this was a great way to make use of the new features without copying over all the events to the new object. Quite a lot of people did this.

It was entirely deliberate that you could do this. In fact, Ini++ v1.5 has a few actions which have no menu items exactly for this purpose. For if they were removed from the code, then this renaming method might not work.

You would expect that if you did this you would see two identical looking objects in the ‘Create new object’ dialog. The same icon, the same text: ‘Ini++ v1.5 Object’. In fact, this is not what you see. Multimedia Fusion will rename the second object to ensure it doesn’t have the same name, so you actually end up with ‘Ini++ v1.5 Object’ and ‘Ini++ v1.5 Object 2’.

The first one (selected in the picture) actually has the file name ‘Ini++.mfx’ and the second has the file name ‘Ini++15.mfx’.

An earlier version of the Ini++ v1.5 Object called itself simply the ‘Ini++ v1.5’ object. Therefore if both ‘Ini++.mfx’ and ‘Ini++15.mfx’ were that version, you would in fact get ‘Ini++ v1.5’ and ‘Ini++ v1.6’ in the dialog, as it intelligently renames. Therefore any object calling itself ‘Ini++ v1.6’ is just an illusion. (Indeed, the title of the object was renamed after it was noticed this happened to avoid this confusion)

But perhaps you are seeing this anyway, despite not being one of the people who renamed ‘Ini++15.mfx’ to ‘Ini++.mfx’? Unfortunately, this is common. The first installer for the first release of Ini++ v1.5 actually installed the file as ‘Ini++.mfx’, which was obviously complicated the situation. (I didn’t make this installer. Later installers install it correctly.) I believe that the one of the extension updaters for MMF will also distribute Ini++ v1.5 with the filename ‘Ini++.mfx’. Combined, this means that nearly everybody will have this problem.

Perhaps I will solve this in future by having the next installer install the original version of Ini++ as well. Or perhaps by making sure it is uninstalled (as you shouldn’t really be using it anymore anyway – it exists only for compatibility reasons now).

So which version is the latest version? Well, it is quite possible they are both the same version. Make sure you are using the version with the file name ‘Ini++15.mfx’ (you can tell this by selecting the object and clicking the ‘About’ tab in the properties viewer). Ensure this is up to date by installing the latest release. If you don’t use ‘Ini++.mfx’, perhaps you should delete it.

Inserting German characters in Windows (Umlauts and eszett)

I’m learning German at the moment, and so I sometimes type things in German. I don’t have a German keyboard, so it can be awkward to insert character which aren’t using in English, like the eszett (ß) or umlauts (ä, ö and ü). On a Mac it is actually very easily – press Command+U and then dots appear in the edit box, and the next button you pretty will have the desired diaeresis.

In fact, it isn’t true that the diaeresis is not used in English. Some people will use them on the second vowel when there are two vowels together, to indicate they are said as two separate sounds. For instance, one might write ‘coöperate’, to show that it is said ‘co-operate’, rather than ‘coop-erate’. ‘Naïve’ is another example.

So, I solved this problem by writing a program called Umalut. It sits in your system tray and when you either click the icon, or press a shortcut (hard coded to Windows Key + S at the moment), it will insert an umlauted character if a vowel or ‘y’ is pressed, or an eszett if ‘s’ is pressed.

It can generate the character in two ways – either by generated a WM_CHAR message directly to the window that it stole the keypress from, or by simulating input and typing out the Alt-code for the character. It is written in C++ and consists of two projects – a GUI and the hook DLL.

The problem is, I’ve broken it at the moment somehow, and I’ve just realised that when you are using Microsoft Word, it is massively easy to insert characters. The default shortcut to insert an umlaut is to press Control+Shift+; and then press the required vowel. For the eszett, it is Control+&, and then ‘s’ (on my keyboard, this is the same as Control+Shift+7 and then ‘s’).

By going into the Symbol shortcut dialog (Insert tab, Symbol, More symbols…, select the eszett and then click ‘Shortcut’) you can change this shortcut. I’ve set it to Control+Shift+; and then ‘s’, so it is the same to access any of the characters I am interested in.

What is more, you can set up auto-correct text. I’ve configured it so that (for instance) ‘..a’ is translated into ‘ä’, which is very convenient. I recommend these to everybody else, too!

For now, I’m not going to bother with releasing the Umlaut program. However I might in the future if there is any demand for it.