Developer's corner

From Winamp iPod plugin ml_iPod
Jump to: navigation, search

This page is dedicated to ml_iPod developers and translators. Hopefully if contains all the info needed to start...



Source code repository

Source code (including translated files) are kept in a CVS repository on To change files, you need to install a CVS client application on your PC (see below). -Not needed for translations-

At you can see the latest revisions of all files in CVS, without the need to install a CVS client on your PC.

Mailing list

All developers and translators should subscribe to the mlipod-devel mailinglist:

Joining the dev team

If you want to code for ml_iPod, you need a SourceForge login, and I must add that login as a member of the ml_iPod dev team. Simply drop me a line on the forum. We're always happy about people who want to get involved. You should have a good knowledge of C++ and MFC. And don't be scared by the mess that ml_iPod code currently is: It has developed over time, a lot is very old code (without MFC), other stuff is MFC, there are some libs that use the STL,... It's a mess - but it works :-)

If you want to make a little patch only, you can simply send me the patch file. No need to become an official SF team member.

If we don't know you and your coding capabilities yet, please do not simply commit any changes on the main development branch. Create a branch in CVS for your changes, and ask me (abu) to check the code before merging it to the main branch. Thanks.

Translating ml_iPod

Translating of ml_iPod is not very complicated. It is a single file that needs to be translated, a so called resource script (*.rc).

The master rc file is called ipod.rc. It is the English resource script. Only this one is updated by the programmers. The other languages are in files like ipod_it.rc for Italian, or ipod_de.rc for German. They must be updated by the translators.

In addition to the *.rc file, there are 4 lines in the ml_ipod.nsi file to be translated (near line 130):

LangString ShowRel   ${LANG_ENGLISH} "Show release notes (important, please read this)"
LangString RunWinamp ${LANG_ENGLISH} "Run Winamp now"
LangString SetupFin  ${LANG_ENGLISH} "Setup finished"
LangString SelDir    ${LANG_ENGLISH} "Please select your Winamp path below$\n(you will only be able to proceed when Winamp is detected there):"

This is for the installer.

You need a software for the CVS only if you want to add modifications to CVS yourself (which is the most convenient way). If you don't want to do that, I recommend using the online CVS of SourceForge that you can find here:

Starting with a new language

To start translating ml_iPod into a new language "xy", simply take the latest version of ipod.rc, copy it to ipod_xy.rc, and translate all strings in this file.

With Visual C++

The easiest way to do this is if you have a copy of MS Visual C++ 6.0 on your PC. You can simply open the *.rc file in VisualStdio, and it will show you all the defined resources (dialogs, strings, menus...) in a tree view. Then you can select one after the other, translate the strings and maybe resize of reposition the dialog elements if needed. Don't resize the whole dialog, please.

Without Visual C++

If you don't have Visual C++, you must load the *.rc file into a text editor (don't use MS Word, it must be a plain ASCII editor) like Notepad, Notepad++, UltraEdit... Then you have to edit the quoted strings, see below. The major drawback of this approach is that you can't see if your strings will fit into the available space. Usuallay one of the developers must revise this later and change size or position manually. That's why the VC++ way is much better.

Combine both for best results

You can also choose a combined way: First translate the strings in the text editor, then as a second step rearrange the dialog layouts in VC++. This is by far the fastest and best way to do it.

Syntax hints

  • Almost everything inside quotes ("...") must be translated, but there are exceptions: Some keywords are in qutes too, but must not be changed:
CONTROL         "Clear Search",IDC_BUTTON_CLEARSEARCH,"Button", BS_OWNERDRAW | WS_TABSTOP,318,1,49,11
  • As a general rule of thumb, always the first quoted string in a given line is the one that needs to be translated, if there is more than one. (Translate "Clear Search" in the example above, but not "Button")
  • Strings must not be longer than 256 chars in the rc file.
  • Quotes within strings are not written \", but with a double quote, like this:
 "This is a quoted ""word"" in a string"

Backslash gives syntax errors:

 WRONG: "This is WRONG and not a quoted \"word\" in a string"    DON'T DO THIS!
  • I once tracked down a bug that was only present in the French and Japanese versions, because in a formatting string there was a "%s" instead of "%d". That caused a Winamp crash. So just keep in mind, your translations have the power to kill Winamp!
    Be extremely careful if there are any "%" signs in a string in the string table. Double check that the characters after the % are the same as in the English reference file, and the order must not be changed.

Keeping you translation up to date

You might be able to copy the new lines (that are shown from the CVS diff) into the previous version of the translated file:

  • Download the latest version of your translated file (it might be changed by a programmer, so make sure you always get the latest version from CVS before you start to add new translated stuff)
  • Download the latest version of the English master file. You can also look at the log of all revisions.
  • Look at the changes in the English file through WebCVS (no installed software needed for this). You should compare the newest English version with the last English revision that you translated. And then incorporate these changes into the Italian (or French, or Japanese...) file.
  • Copy/Paste only these changes to your file
  • Translate these parts
  • Send the changed file via mail to abu

During development, sometimes programmers have to add something to the different resource files, just to make it compile. So they add the English version to all foreign language files, too. That's why the version numbers increase. And that's why I ask to take the latest version of CVS as the basis. That is true for every translation. Forget what you sent me last time, simply take the latest version from CVS. No need to keep any old versions for yourself.

Anyway why localized resource files don't have the same version number as English ones?

This is a typical CVS issue. Every single file has its own revision numbering. So, if I make 10 changes to the English file, the version number increases every time and is n+10 after all these changes. If, at the same period of time, I make 2 changes to the Italian file, that changes only to m+2. More on that see

A release of a complete SW package in CVS is always marked with "tags".

If you look at the revision log, you can see that revision 1.126 has CVS tag r2_04. Thus this revision was used to build the release 2.04.

Usually there are a lot of revisions of this file between two official ml_iPod releases, so only a small number of the revisions are tagged with a release number.

Interpreting the diff screen

To look at the diffs, you can select the latest revision that you already translated in the revision log for diffs (click on "[select for diffs]") and then click on the link "Diff to.. selected" for the newest revision. That will show you a diff listing

A different approach is to type the URL like This example will compares revision 1.108 (r1) to 1.114 (r2 in the URL). You can simply change the numbers to get other revisions.

Green is most important, that is all the newly added stuff.

Yellow are changes. You should have a look at the changed lines, most of the time it is just a reformatting that Microsoft VisualStudio did (I have no idea why it does such stupid things...). But sometimes it is a change within a string. Then it is up to you to check if a change in your language is appropriate. Changes in numeric constants are usually a repositioning or resizing of certain items.

Red will rarely be seen, that are removed lines. Usually we don't remove stuff, but if you ever see it, try to remove the corresponding lines from the language file, too.

Using checkrc to find problems

I wrote a little tool for ml_ipod developers. It is used to check your translated rc file.

Download checkrc.exe at

Then simply copy the newest(!) ipod.rc, your translated ipod_xx.rc and the application checkrc.exe into one folder. Doubleclick the app, a window opens and shows you the result of the check.

It checks if all dialogs (IDs) are present, nothing missing, no needless stuff in it, and if all controls in the dialogs are there and in the right order. It can't check size or positions. But it's much better than nothing. Always make sure that checkrc yields no more problems before sending a translated file!

(See the announcement mail for examples of the usage)

Coding for ml_iPod

Recommended Tools

  • MS Visual C++ 6 (only use this as IDE and compiler!)
  • WinCVS / cvsnt (or TortoiseCVS, whichever fits your taste)
  • WinMerge for showing diffs (must be configured as external diff tool in WinCVS or TortoiseCVS)
  • PuTTY (A Free Telnet/SSH Client) to create the SSH key pair needed for CVS access

Good Style

  • In Options->Tabs: Tab size is 8, Indent size is 2, use "Insert spaces" only
  • ALWAYS make a diff of your changes before you commit to CVS. Check if only INTENDED changes are in your files.
  • Especially for resource files, which get formatted by MSVC: make sure that there are no unwanted changes.
  • If you create new files, don't forget to add them to CVS
  • What is checked in to CVS must ALWAYS be compilable

CVS access

For small changes and patches, you do not need a account, you can simply checkout the latest version of all files via anonymous CVS (pserver). Then you can make your changes, test everything, create a patch file (there is an option in WinCVS to do that) and send that to abu (use the forum PM). He will check the changes and add them to CVS. That is the preferred way for new contributors (we need to see a bit of your coding skills and quality first :) )

For more serious changes you need a account to have direct CVS write access. Then, one of the project admins has to add you to the project team member list. Now you must setup you CVS client, and create a SSH key.

Regarding CVS, there are some documents available at SourceForge, mainly

CAUTION: These links are all outdated! SourceForge changed the repository. Sorry.

These docs must be read and understood by every developer :-(

CVSROOT: I use this CVSROOT, which works fine with CVSNT/WinCVS/TortoiseCVS


With PuTTY, create a SSH key pair, and store it somewhere secure (these are two files, one with a *.pub extension, one without) I called it "sourceforge" and ""

There are two parts in CVSROOT that you must update:

  • The username (achim66) must be your SourceForge login
  • The privatekey (d:\achim\ssh\sourceforge) must be the full path to your private SSH key. Make sure that you posted the public key corresponding to this to SourceForge first, or you will have no access to the CVS repository

Links to manage your SSH keys on the SF site may be found on the SF Account Maintenance page. Make sure that you post your public key there!

In a command window, change to the ml_ipod folder (not the CVS subfolder!) and issue the command

            \path\to\cvsnt\cvs.exe update -P -d

or use WinCVS or TortoiseCVS to do an update. This should download all the files from SourceForge Personally, I use WinCVS most of the time.

Rules for CVS commits

  • everything you commit must be compilable
  • always use a separate branch for your changes (unless told anything different by the project admins) - make sure you know what branching in CVS is all about. If you don't know, read a beginners guide to CVS, there are some tutorials available on the web.
  • on your branch, you can change and commit whatever you want
  • if you are ready for a merge to main (which means putting your changes into the main code base), one of the admins must check your changes first
  • Never merge to main without being told so by one of the admins

Building ml_iPod

  • open Workspace ml_ipod.dsw in VC6
  • choose project ml_ipod
  • build the project (Debug version), everything should build without errors or warnings
  • now, if you edit files, you can commit them to CVS whenever you want
  • make sure to add newly created files to CVS

Coding hints

Most part of the GUI is plain Win32 API, only the newer parts are MFC (this is what I introduced). The MFC part is easier to understand and code, but still messy because the Winamp interface is not MFC compliant, and Winamp is not an MFC app. So it's crucial to call some special MFC macro every time you enter a function from outside:

 AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

For the MFC pref pages: I created some helper macros, like this

TRANSFER_TO_DIALOG_BEGIN(); // transfer from global variables or iPod members
G_TRANSFER(g_useAudioScrobbler, m_useLastFm );
G_TRANSFER(g_audioScrobblerSubmitMode, m_submitMode);

Very helpful to use the VC sourcebrowsing info (F12) to go the definitions.

The definition of preferences is done centrally in one header file:


Older prefs are coded in other ways, but it is the goal to change all the other prefs to this new scheme. It is easily maintainable, because there is only one place to edit if you want to add a new prefs setting.

As of Apr 23 2007, the ml_ipod CVS repository is fully selfcontained, no external libs or SDK necessary (up to then, it was necessary to have a recent version of the Winamp SDK installed first).

Debugoutput: Use the DBG macro, provided in dbg.h.

iostream: Unfortunately, there are incompatibilities in the usage of the iostream libs. ml_ipod uses e.g. <fstream.h>, the used id3lib uses the newer <fstream>. They can't be used together in one file, or you will get problems.

When closing Winamp, you often get an unhandled exception while running the debugger. I have no idea where that comes from :-(


Whenever a new publically available installer is created, the version number must be incremented in versions.h.

To create an installer, NSIS must be installed on the PC.

If you run NSIS on ml_ipod.nsi, you get a full installer with all libs and languages included. ~ 1MB

If you run NSIS on versions.h, you get a patch installer with no libs and English only. This is < 300KB

To do for a new release

This is a ToDo list for an official ml_iPod release

  • Edit the file "version.h" for the release number
  • Maybe increase donationRequestNumber in ml_plugin.cpp
  • Edit the change log (build number, date!)
  • Edit the releasenotes.rtf
  • in VisualStudio build the "installer" project, which does
    • choose "Win32 Release" as active configuration
    • Build ml_ipod and all res_XX projects
    • Create installer with NSIS (ml_ipod.nsi)
  • checkin all files to CVS
    • put label on all in CVS: e.g. r2_04
  • Create new file relase at Sourceforge, name e.g.: 3.02
  • Upload the ml_ipod_changelog.txt to sourceforge: /home/groups/m/ml/mlipod/htdocs
  • Upload the ml_ipod_changelog.txt to sourceforge patch area, with the web interface
  • Edit the file "updatecheck.php"and "versiondef.php" in s for the automatic update checks (updatecheck.php must contain up to 4 lines of information about the release, versiondef can define a different version for each language)
  • Remove the file "versiondef.php" in s if it exists
  • Update the main website, => pages/home.php
  • Announce on WinAmp forum:
  • Change last release in the FAQ/Wiki
Personal tools
Translations of the Wiki