Ubuntu has come a long way in the past few years. I've been using it as my only desktop OS since Hoary, and it's come along in leaps and bounds. There are however a number of things that just seem to be "missing".
This list is a set of GUI apps that I have discovered to be missing, either on my own desktop (1, 2, 3, and 5) or while installing Ubuntu for friends (4).
Thursday, 21 October 2010
Wednesday, 13 October 2010
Mellowing the Ubuntu Indicator Applets
Update: As of Ubuntu 11.04 Canonical has switched to using light blue icons for notifications. So, I can officially say "I told you so" :)
One thing that has bugged me since Canonical launched their Indicator Applet work was their chosen colour system. I'll explain...
One thing that has bugged me since Canonical launched their Indicator Applet work was their chosen colour system. I'll explain...
Friday, 8 October 2010
Step Back to the 90s with this Mega Drive Emulator for Ubuntu
This post is a cross-post from Ubuntu Gamer
I don't know about you guys and girls, but sometimes I like reminiscing about my childhood by playing some good old Mega Drive (Genesis for those across the pond) games. You can't beat a good round of Sonic.
When it comes to Mega Drive emulators that run on Ubuntu, Gens/GS rocks. Gens/GS is a fork of the well known Gens emulator, and over the last several months the author has been cleaning up the source code and adding new features and bug fixes to create an awesome (open source!) emulator.
Tuesday, 5 October 2010
Using Multiple Wine Prefixes
This post is a cross-post from Ubuntu Gamer
Wine rocks. It is probably one of the most underestimated pieces of software in the open source ecosystem. If the idea of running pre-compiled programs from Windows on a totally different operating system with a different kernel, and different programming libraries doesn't make you cross-eyed with the complexity, then you aren't thinking about it hard enough.
Just to give some idea of the Herculean achievement that Wine is; the current number of lines of code that make up Wine stands at well over 2.5 million and the project was started in 1993.
The Wine developers don't just have a mountain to climb. To extend the metaphor, they have to climb the mountain, blindfolded, in a straight jacket while tied to a goat... drunk. Their work really is that hard.
Yet despite all that effort, Wine still isn't 100% perfect. Sometimes a Wine DLL will be missing some code, other times the code may not match what Windows does and occasionally a program assumes the existence of files that may not even necessarily exist on a native Windows installation (e.g. .NET).
Monday, 20 September 2010
Amnesia: The Dark Descent
Just a quick blog post to plug what looks like an amazing game: Amnesia: The Dark Descent
Take a look at the video!
I haven't bought Amnesia yet (mainly due to having not completed the awesome predecessor, Penumbra yet) but by the sound of it it's a great game, and available for Linux DRM-free! Check it out!
Take a look at the video!
I haven't bought Amnesia yet (mainly due to having not completed the awesome predecessor, Penumbra yet) but by the sound of it it's a great game, and available for Linux DRM-free! Check it out!
Rooted your Orange Dext and the Browser isn't Working?
An odd problem started the other day after I rooted my (Orange UK!) Dext, it wasn't immediate - I'm not sure what I did... anyway, the issue was that the default Android Browser wouldn't load any pages over 3G, neither would SkyFire, but Opera Mini would.
After some prodding and Googling I figured out how to fix it, here's how:
1. Navigate to Settings -> Wireless & networks -> Mobile networks -> Access point names
2. Select "orangeinternet"
3. Set the "Name" to "orangeinternet" (you must enter a name, and apparently there isn't one)
4. Select "Proxy" and clear the box (mine said "null")
5. Select "Port" and clear the box (mine again said "null")
6. Select "Server" and clear the box (again, "null")
7. Make sure the "User" is "user" (I didn't need to change this)
8. That's it, probably best to reboot the phone
That fixed it for me, hope someone finds it useful.
After some prodding and Googling I figured out how to fix it, here's how:
1. Navigate to Settings -> Wireless & networks -> Mobile networks -> Access point names
2. Select "orangeinternet"
3. Set the "Name" to "orangeinternet" (you must enter a name, and apparently there isn't one)
4. Select "Proxy" and clear the box (mine said "null")
5. Select "Port" and clear the box (mine again said "null")
6. Select "Server" and clear the box (again, "null")
7. Make sure the "User" is "user" (I didn't need to change this)
8. That's it, probably best to reboot the phone
That fixed it for me, hope someone finds it useful.
Friday, 10 September 2010
OilRush to be DRM free on Linux!
OilRush is an upcoming game based on the Unigine engine. It looks amazing, check out the trailer:
If you read my previous StarCraft 2 rant, you'll know that I hate DRM and refuse to buy games that are DRM encumbered. So after some prodding by me over on the Phoronix forums one of the OilRush developers announced the following:
If there will be no major objections from the distributor, we plan to release at least Linux version without DRM.
This is brilliant news. Good going Unigine Corp.!
If you read my previous StarCraft 2 rant, you'll know that I hate DRM and refuse to buy games that are DRM encumbered. So after some prodding by me over on the Phoronix forums one of the OilRush developers announced the following:
If there will be no major objections from the distributor, we plan to release at least Linux version without DRM.
This is brilliant news. Good going Unigine Corp.!
Sunday, 5 September 2010
Putting Android 2.1 (adlxmod) on a UK Orange Dext
Motorola suck. They really REALLY suck and I'm not buying anything manufactured by them in future and I'd recommend others don't either. Last year, when Android phones were really beginning to hit the market, I spent quite a while choosing the right one for me. I really wanted a keyboard and the price had to be right, so at the time the only option was the Dext on Orange. It was running Android 1.5 but I *knew* that Android phones get upgraded, right? Wrong.
Motorola have promised an update to the U.S. release of the Dext (called the Cliq) for some time, but the upgrade path in Europe, S. America and elsewhere was labelled "Evaluation in progress". This was the case for months and months. The upgrade website wasn't updated but a lead figure at Motorola had announced that all Dext phones would be upgraded to 2.1. This announcement led to many more people rushing out to buy a Dext. Unfortunately it was a lie.
On August 23rd, after 6-8 months of waiting for an update. The update status website change from "Under evaulation" to "Europe will not be getting the update". Unsurprisingly, Dext owners are really angry, not just because they were lied to, not only because they were strung along for 8 months, but because the U.S. Cliq is getting the update but Motorola can't be arsed to push it out over here! The software exists, we just can't get it. So, you have a UK Dext and want Android 2.1 - then you need to take matters into your own hands...
Motorola have promised an update to the U.S. release of the Dext (called the Cliq) for some time, but the upgrade path in Europe, S. America and elsewhere was labelled "Evaluation in progress". This was the case for months and months. The upgrade website wasn't updated but a lead figure at Motorola had announced that all Dext phones would be upgraded to 2.1. This announcement led to many more people rushing out to buy a Dext. Unfortunately it was a lie.
On August 23rd, after 6-8 months of waiting for an update. The update status website change from "Under evaulation" to "Europe will not be getting the update". Unsurprisingly, Dext owners are really angry, not just because they were lied to, not only because they were strung along for 8 months, but because the U.S. Cliq is getting the update but Motorola can't be arsed to push it out over here! The software exists, we just can't get it. So, you have a UK Dext and want Android 2.1 - then you need to take matters into your own hands...
Thursday, 29 July 2010
Starcraft 2's DRM fail
I've been out of the loop of mainstream PC games for a while, tending to buy Wii games or DRM-free indie PC games such as Osmos or the Humble Indie Bundle. But every now and then a game pops up on the news that I really really want. Last time this game was Spore, and then I found out about the DRM and I didn't buy it. Now this time it's Starcraft 2.
I remember playing the first Starcraft and loved it. I loved the look of Starcraft 2, but again another big game company fucks up by crippling it with DRM in the fruitless aim to reduce piracy.
Let me spell it out for you: DRM DOES NOTHING TO STOP "PIRACY" AND EVERYTHING TO PISS OFF YOUR CUSTOMERS!
I hear Starcraft 2 has already been cracked, so what was that, 1 day after release? Good going Blizzard, you've pissed off your customers for nothing. So, I will NOT be buying Starcraft 2 and judging from the comments on Amazon, I'm not the only one.
Seriously Blizzard. Get a clue.
I remember playing the first Starcraft and loved it. I loved the look of Starcraft 2, but again another big game company fucks up by crippling it with DRM in the fruitless aim to reduce piracy.
Let me spell it out for you: DRM DOES NOTHING TO STOP "PIRACY" AND EVERYTHING TO PISS OFF YOUR CUSTOMERS!
I hear Starcraft 2 has already been cracked, so what was that, 1 day after release? Good going Blizzard, you've pissed off your customers for nothing. So, I will NOT be buying Starcraft 2 and judging from the comments on Amazon, I'm not the only one.
Seriously Blizzard. Get a clue.
Friday, 18 June 2010
Hurdles when Porting Games to Linux
A recent Shot of Jaq episode described the many problems that indie game developers face when porting their games to Linux, let's break down the problems into categories:
1. Which libraries do I use?
2. How do I package the game?
So here we go.
Which libraries do I use?
This is the one that people make the most fuss about. When developing a game on Windows, you know full well that if you want to create a 3D enabled window, you have Win32 + Direct3D + DirectSound (or whatever it is now) right there. And it works. It works because the whole Windows game world develops using those APIs and they are well tested. When coming over to develop for Linux, many devs don't know where to look for the equivalents, and when they ask around they get different answers from everyone, because people recommend what they like, not what is the most sensible option. Let me answer the question right now:
1. For graphics, use OpenGL 2.1 (or 1.5 if you don't need GLSL)
2. For sound, use OpenAL
3. For windowing and input, use SDL
Now, before I get ransacked by people with opinions, I'll explain why :)
Graphics
This is the easiest one to decide. OpenGL is the only choice for hardware accelerated graphics on Linux. If you can do without shaders and target 1.5 you can get the lower end hardware, if you need shaders then go for 2.1 rather than 3.x or 4.x because Mesa doesn't support them (yet) and the open source ATI and Intel drivers both support it. You can of course check the version at runtime if you want 3.x or 4.x features, but don't rely on it.
Sound
This is the one that causes the most noise (no pun intended), ALSA? Pulse? OSS? etc. No you want OpenAL. OpenAL gives you a consistent 3D sound API that wraps the underlying complexity of various sound systems. It's not perfect, but it's definitely your best choice. Hemisphere games came to the same conclusion when porting Osmos. Just go with it and test as much as possible. openal-soft has a number of backends too, so if you don't have Pulseaudio, or whatever, it will still work. The openal-soft developers are really responsive. I had a load of help trying to diagnose a problem with openal + pulse (which was a bug fixed some time ago now).
Windowing and Input
I can tell this will stir up a hornets nest of people saying that straight X is better, and indeed straight X is what the Osmos developers went with. But SDL has been used for a load of games (World of Goo, Penumbra, Quake 4 etc.) it's pretty damn good. Again, it wraps the complexity of the underlying X and handles any quirks for you. Also the SDL developers are responsive to both feature requests and bug reports, and have a really busy mailing list. If you have any trouble, you have somewhere to go and get it fixed. If you don't think SDL is flexible enough, then go with X, but let me assure you - you'll be writing a lot more code, and that code is your problem.
There, done. By offloading the work to these libraries you get a number of advantages:
1. Bugs you find and report (and perhaps even fix) help everyone
2. They deal with the hard work for you, reducing the amount you need to code
3. They are widely available
4. All three of them have nice, consistent APIs
Packaging the Game
Packaging is a pain in the arse if you want to target as much of the Linux-based ecosystem as possible. Generally though, packaging in .deb, .rpm and .tar.gz in both 64 bit and 32 bit versions seems the way to go. Games in The Humble Indie Bundle were packaged in various different ways, but World of Goo had a .deb package that worked the best compared to the fiddling I had to do to get the others to run.
It's probably best to go with the distributions package manager to handle dependencies, especially for the big 3 libraries (GL, AL, SDL) and also FreeType and libvorbis. That's the approach Hemisphere games took and they seem pretty happy with the result.
Other Libraries
Obviously it's not just graphics, sound, input and windowing you need to worry about, here are some suggestions for other libraries:
1. Fonts - Freetype2
2. Image loading - Take a look at SOIL
3. OpenGL extension handling - GLee is popular, but not included in the Ubuntu repos, GLew does the same job and is in the repos.
4. Physics - Box2D for 2D, ODE for 3D
1. Which libraries do I use?
2. How do I package the game?
So here we go.
Which libraries do I use?
This is the one that people make the most fuss about. When developing a game on Windows, you know full well that if you want to create a 3D enabled window, you have Win32 + Direct3D + DirectSound (or whatever it is now) right there. And it works. It works because the whole Windows game world develops using those APIs and they are well tested. When coming over to develop for Linux, many devs don't know where to look for the equivalents, and when they ask around they get different answers from everyone, because people recommend what they like, not what is the most sensible option. Let me answer the question right now:
1. For graphics, use OpenGL 2.1 (or 1.5 if you don't need GLSL)
2. For sound, use OpenAL
3. For windowing and input, use SDL
Now, before I get ransacked by people with opinions, I'll explain why :)
Graphics
This is the easiest one to decide. OpenGL is the only choice for hardware accelerated graphics on Linux. If you can do without shaders and target 1.5 you can get the lower end hardware, if you need shaders then go for 2.1 rather than 3.x or 4.x because Mesa doesn't support them (yet) and the open source ATI and Intel drivers both support it. You can of course check the version at runtime if you want 3.x or 4.x features, but don't rely on it.
Sound
This is the one that causes the most noise (no pun intended), ALSA? Pulse? OSS? etc. No you want OpenAL. OpenAL gives you a consistent 3D sound API that wraps the underlying complexity of various sound systems. It's not perfect, but it's definitely your best choice. Hemisphere games came to the same conclusion when porting Osmos. Just go with it and test as much as possible. openal-soft has a number of backends too, so if you don't have Pulseaudio, or whatever, it will still work. The openal-soft developers are really responsive. I had a load of help trying to diagnose a problem with openal + pulse (which was a bug fixed some time ago now).
Windowing and Input
I can tell this will stir up a hornets nest of people saying that straight X is better, and indeed straight X is what the Osmos developers went with. But SDL has been used for a load of games (World of Goo, Penumbra, Quake 4 etc.) it's pretty damn good. Again, it wraps the complexity of the underlying X and handles any quirks for you. Also the SDL developers are responsive to both feature requests and bug reports, and have a really busy mailing list. If you have any trouble, you have somewhere to go and get it fixed. If you don't think SDL is flexible enough, then go with X, but let me assure you - you'll be writing a lot more code, and that code is your problem.
There, done. By offloading the work to these libraries you get a number of advantages:
1. Bugs you find and report (and perhaps even fix) help everyone
2. They deal with the hard work for you, reducing the amount you need to code
3. They are widely available
4. All three of them have nice, consistent APIs
Packaging the Game
Packaging is a pain in the arse if you want to target as much of the Linux-based ecosystem as possible. Generally though, packaging in .deb, .rpm and .tar.gz in both 64 bit and 32 bit versions seems the way to go. Games in The Humble Indie Bundle were packaged in various different ways, but World of Goo had a .deb package that worked the best compared to the fiddling I had to do to get the others to run.
It's probably best to go with the distributions package manager to handle dependencies, especially for the big 3 libraries (GL, AL, SDL) and also FreeType and libvorbis. That's the approach Hemisphere games took and they seem pretty happy with the result.
Other Libraries
Obviously it's not just graphics, sound, input and windowing you need to worry about, here are some suggestions for other libraries:
1. Fonts - Freetype2
2. Image loading - Take a look at SOIL
3. OpenGL extension handling - GLee is popular, but not included in the Ubuntu repos, GLew does the same job and is in the repos.
4. Physics - Box2D for 2D, ODE for 3D
Friday, 11 June 2010
Clearing FileFields in Django's admin
This post is as much a reminder for me as it will be helpful to others. Yesterday I added a couple of FileFields to a Django model, the point of them is to allow overriding of some site images. So the idea is that you can upload images or swf files to these fields, they'll replace the ones on the site, until you are bored of them then you can delete them and the original images will be restored.
After adding the FileFields to the model, they nicely appeared in the Django admin site. I uploaded an image, the override worked perfectly, now to restore the original image...
And that's where you hit a problem. There is no way in the Django admin to clear a FileField, you can replace it, but you can't clear it to NULL. Happily there is a workaround[1]. You first need to create a custom ModelForm for your model which includes an extra checkbox like so:
class MyCustomForm(ModelForm):
clear_the_image = forms.BooleanField("Clear the image", required=False)
class Meta:
model = MyModel
def save(self, commit=True):
model_instance = super(MyCustomForm, self).save(commit=False)
if self.cleaned_data.get('clear_the_image'):
model_instance.the_file_field = None
if commit:
model_instance.save()
return model_instance
Then in your MyModelAdmin class:
class MyModelAdmin(ModelAdmin):
form = MyCustomForm
That's it. When you save the form, it will see if you asked to clear the image, if so it will set it to None and then save. Job done.
[1] Adapted from this: http://www.developerit.com/2010/04/17/django-admin-add-a-remove-file-field-for-image-or-filefields
After adding the FileFields to the model, they nicely appeared in the Django admin site. I uploaded an image, the override worked perfectly, now to restore the original image...
And that's where you hit a problem. There is no way in the Django admin to clear a FileField, you can replace it, but you can't clear it to NULL. Happily there is a workaround[1]. You first need to create a custom ModelForm for your model which includes an extra checkbox like so:
class MyCustomForm(ModelForm):
clear_the_image = forms.BooleanField("Clear the image", required=False)
class Meta:
model = MyModel
def save(self, commit=True):
model_instance = super(MyCustomForm, self).save(commit=False)
if self.cleaned_data.get('clear_the_image'):
model_instance.the_file_field = None
if commit:
model_instance.save()
return model_instance
Then in your MyModelAdmin class:
class MyModelAdmin(ModelAdmin):
form = MyCustomForm
That's it. When you save the form, it will see if you asked to clear the image, if so it will set it to None and then save. Job done.
[1] Adapted from this: http://www.developerit.com/2010/04/17/django-admin-add-a-remove-file-field-for-image-or-filefields
Friday, 14 May 2010
The Humble Indie Bundle on Ubuntu AMD64
Just a quick post, because basically I couldn't find this information elsewhere and I'm hoping someone finds it useful. Like thousands of other people I bought the Humble Indie Bundle while it was on sale and it is amazing. However, for ages I had no luck installing Lugaru. I kept getting messages like this:
kazade@argon ~ $ chmod +x lugaru-full-linux-x86-1.0c.bin
chmod: cannot access `lugaru-full-linux-x86-1.0c.bin': No such file or directory
kazade@argon ~ $ chmod +x /home/kazade/Downloads/lugaru-full-linux-x86-1.0c.bin
kazade@argon ~ $ ./lugaru-full-linux-x86-1.0c.bin
bash: ./lugaru-full-linux-x86-1.0c.bin: No such file or directory
If you have this problem, the solution is to install the ia32-libs package. Then the installer will run, simple eh?
kazade@argon ~ $ chmod +x lugaru-full-linux-x86-1.0c.bin
chmod: cannot access `lugaru-full-linux-x86-1.0c.bin': No such file or directory
kazade@argon ~ $ chmod +x /home/kazade/Downloads/lugaru-full-linux-x86-1.0c.bin
kazade@argon ~ $ ./lugaru-full-linux-x86-1.0c.bin
bash: ./lugaru-full-linux-x86-1.0c.bin: No such file or directory
If you have this problem, the solution is to install the ia32-libs package. Then the installer will run, simple eh?
Monday, 3 May 2010
The Ambiguity of Hiding Windows
So, Ubuntu 10.04 LTS has been released and it is pretty damn awesome. Again I don't think it was entirely ready, I think more time could have been spent fixing video driver bugs because there are a lot of people complaining about hitting a "black screen" (see my brainstorm idea: http://brainstorm.ubuntu.com/idea/24727/ ).
Anyway, one of the features of Lucid is the new indicator applet, designed to replace the notification area with a consistent interface. I love the indicator applet, except for one thing, this:
The indicator applet replaces the menu functionality for the icon brilliantly but it goes a little too far in replicating the functionality of the notification area. This is a long standing bug bear of mine. Many apps on Windows, and then consequently other desktops, allow minimizing an application to an icon. Why?
To clear the window off of the desktop? That's what minimize is for. "But.. but.. then it clutters my taskbar!" I hear you cry, and that my friends is the point, the minimize to icon functionality is a workaround, a plaster over the fundamentally broken taskbar. The main problem with the current window switcher is the size of the elements. Even with a widescreen monitor you can fill it up pretty quick because window titles take up a lot of space. Application grouping helps to some extent but each element still takes up more room than the icon would do alone.
But that's not the only reason for the existence of "minimize to tray". When you are looking for a window in a list of windows, the less there are the easier it is. That's why you don't want Rhythmbox, or your IM contact list cluttering up the bottom. So the flaws with the window switcher are:
1. Each element takes up too much space
2. There are too many elements
You can also add:
3. You can't read the entire titles on the windows
We can easily solve these problems. Windows 7 had the right idea by replacing the window items with icons. We have a decent alternative on Ubuntu too, it's called DockbarX.
Don't believe me, try this. Add the DockbarX PPA and replace the window switcher applet with DockbarX. Now, make your Rhythmbox visible via the indicator applet and minimize it. Now go ahead and work with your computer. What do you notice? It takes up hardly any room AT ALL, in fact you won't even notice it's there because every time you go down to that Dockbar you'll be going there for an application window and finding the application is dead easy when its icon is right there and there is only one of them. Hover over the application icon and bingo, up pops the list of windows for that application with FULL TITLES.
Rhythmbox won't get in the way because you won't be drawn to it you are looking for a bright orange Firefox window for example. And you can open a shedload of windows and still have plenty of space in the taskbar. If you wanna skip a track, or see what's playing then you can do, using the indicator applet.
So, if there is one thing I would do if I was in charge of 10.10 it would be this: replace the window-switcher applet with DockbarX and remove any minimize to tray functionality from the indicator applets. It removes the ambiguity of "where did I minimize that window to" and it makes life much MUCH easier and consistent.
Anyway, one of the features of Lucid is the new indicator applet, designed to replace the notification area with a consistent interface. I love the indicator applet, except for one thing, this:
The indicator applet replaces the menu functionality for the icon brilliantly but it goes a little too far in replicating the functionality of the notification area. This is a long standing bug bear of mine. Many apps on Windows, and then consequently other desktops, allow minimizing an application to an icon. Why?
To clear the window off of the desktop? That's what minimize is for. "But.. but.. then it clutters my taskbar!" I hear you cry, and that my friends is the point, the minimize to icon functionality is a workaround, a plaster over the fundamentally broken taskbar. The main problem with the current window switcher is the size of the elements. Even with a widescreen monitor you can fill it up pretty quick because window titles take up a lot of space. Application grouping helps to some extent but each element still takes up more room than the icon would do alone.
But that's not the only reason for the existence of "minimize to tray". When you are looking for a window in a list of windows, the less there are the easier it is. That's why you don't want Rhythmbox, or your IM contact list cluttering up the bottom. So the flaws with the window switcher are:
1. Each element takes up too much space
2. There are too many elements
You can also add:
3. You can't read the entire titles on the windows
We can easily solve these problems. Windows 7 had the right idea by replacing the window items with icons. We have a decent alternative on Ubuntu too, it's called DockbarX.
Don't believe me, try this. Add the DockbarX PPA and replace the window switcher applet with DockbarX. Now, make your Rhythmbox visible via the indicator applet and minimize it. Now go ahead and work with your computer. What do you notice? It takes up hardly any room AT ALL, in fact you won't even notice it's there because every time you go down to that Dockbar you'll be going there for an application window and finding the application is dead easy when its icon is right there and there is only one of them. Hover over the application icon and bingo, up pops the list of windows for that application with FULL TITLES.
Rhythmbox won't get in the way because you won't be drawn to it you are looking for a bright orange Firefox window for example. And you can open a shedload of windows and still have plenty of space in the taskbar. If you wanna skip a track, or see what's playing then you can do, using the indicator applet.
So, if there is one thing I would do if I was in charge of 10.10 it would be this: replace the window-switcher applet with DockbarX and remove any minimize to tray functionality from the indicator applets. It removes the ambiguity of "where did I minimize that window to" and it makes life much MUCH easier and consistent.
Monday, 8 March 2010
Where I'd put the buttons
Recently during the Ubuntu 10.04 (Lucid Lynx) testing cycle, Canonical introduced new branding and themes. The themes are really nice, still a little rough around the edges, but come launch date they will be slick. However, sneaked into this re-branding was a change that was initially thought to be a mistake.
The window controls moved.
The window controls (Minimize/Maxmize/Close) moved from the right hand side of the window, to the left hand side of the window. Not only that, but minimize and maximize swapped places; just to confuse everyone that little bit more.
Now, the problems with this have been discussed many times over the last week so I'm going to be a bit more constructive on the matter. I'm going to explain what they should have done in my opinion (!).
Now, let's get a few things straight. Firstly, if a button is at the corner of the window it is easier to hit. Secondly, if a button is destructive, it should not be next to a common action (in case of a miss-hit). Thirdly, I'm going to ignore right clicking, and double clicking on the title bar, these things are visually non-discoverable you need to find them by accident, and just cause you know about them doesn't mean everyone does. Got it? Good.
The Close Button
The window controls moved.
The window controls (Minimize/Maxmize/Close) moved from the right hand side of the window, to the left hand side of the window. Not only that, but minimize and maximize swapped places; just to confuse everyone that little bit more.
Now, the problems with this have been discussed many times over the last week so I'm going to be a bit more constructive on the matter. I'm going to explain what they should have done in my opinion (!).
Now, let's get a few things straight. Firstly, if a button is at the corner of the window it is easier to hit. Secondly, if a button is destructive, it should not be next to a common action (in case of a miss-hit). Thirdly, I'm going to ignore right clicking, and double clicking on the title bar, these things are visually non-discoverable you need to find them by accident, and just cause you know about them doesn't mean everyone does. Got it? Good.
The Close Button
This is the one. This is the real cause of the complaints from users. There are two things special about this button.
- It's destructive. The only really destructive of the three.
- It's the most used. Of all the buttons it's the only one that must be there.
(Note, obviously, most used is dependent on user habits which is why we need usability testing - which I haven't done. But according to my logic it must be used at least once, which is more than the other two.)
Why is it the only one that must be there? Well, because you can use the taskbar to minimize or switch applications or you can resize the window to fullscreen. You cannot (in a easily discoverable way) close all windows without that button being there (before anyone says it; not all windows have menus).
So, because it's destructive, it should be well away from other common actions on the window. Let's take a look at a window shall we:
So, where do we put the close button? Well, the left hand side has a bunch of common actions, so we should probably steer clear of that side (take note Canonical!). That leaves anywhere right of the Help menu... as an applications can have many menus and can be resized so they are smaller, it would make sense to put it as far away as possible – so yeah on the right.
Now, onto usage, because the close button is the only action that must be performed, it makes sense to have it in a corner, that way you can hit it more easily. So, let's put that one there:
So cool, that's that one done, now let's move onto the next one...
The Maximize Button
So, arguably this is the next most important button, the reason? Well, you minimize to get to windows behind the one you are using, which you can do with the taskbar. Maxmize can only be done by drag-resizing (a pain) or right clicking (non-discoverable). So, after close it's pretty important. So, where do we put it? Well, a corner would make sense, but what if we put it next to the close button anyway? Well, there you've broken one of my rules above, you've put a common action next to a destructive action. So, let's just put maximize on the other corner:
Now the final button (or is it?)
The Minimize Button
So, this one is easy. It's a non-essential, non-destructive button. So, following logic it can go anywhere that's not next to a destructive item. Well, that just leaves next to the maximize button, but it doesn't need a corner so let's put it the other side:
There, for balance you should probably choose a theme with a centered title. But still, this layout makes more sense. You reduce the risk of closing something accidentally, and the most used items are in the corners. As a side effect you also keep two related options (minimize and maximize) close together.
What About the Menu Button?
I'm a bit ambivalent about this one, I'm not really sure where it belongs. The other three buttons change the size of the window (or make it go away) and don't pop-up a menu. It doesn't really fit with the others, (also the functionality is available on right-click, albeit undiscoverable). If I was to choose a position, I'd put it next to minimize, but I think it's arguable whether it needs to be included at all.
Conclusion
I'm no usability expert, but if I was to redesign the location of the buttons, (which, I'm not sure they need redesigning and breaking that muscle memory) that's where I'd put them. Also it has the pleasant side-effect that the close button doesn't move from the “normal” arrangement. I'd be happy if Canonical changed to this way, at least there is some obvious logic behind it... obvious logic makes me happy.
Friday, 19 February 2010
OpenALSoft/Pulseaudio: it's not me, it's you.
I learnt a valuable lesson this week. If you have rewritten your code 3 times, and your tests all pass and you understand every part of it and yet it still doesn't work ... it's probably something not to do with you.
Last weekend I decided it was time my game gained some sound. I'd just finished the game menu screen and figured that some music would make it seem a little more complete. In an attempt to follow the KISS principle I decided to keep it simple, I'd write a class that just plays an OGG file in 2D. No multiple sources, no bells and whistles, nothing fancy, just load an OGG and play it. A quick Google search turned up this gem of a tutorial, so I figured it was a 10 minute job. When the time came to do more, I'd look for a decent high-level library, or just steadily build on my simple base code but for now, I figured, following this tutorial would teach me a little OpenAL then I could move on.
And for a little while I was right. I wrote my class, loaded an OGG file and played it with OpenAL by loading it into a single buffer and binding the buffer to the source before calling alSourcePlay(). It worked!
...
For about 2 seconds. Then it crackled and went silent.
I assumed that the problem was the track I was playing was too long to be bound in a single buffer, and instead I figured I should break it into smaller buffers and feed it into the source to play. Possibly a bad assumption, I guess I should've tried playing a smaller sound to see if that was actually the case - but I was having fun, and queueing the buffers looked simple enough.
So I got to work, I decoded the OGG stream into a vector of vector<char>'s the idea being that as room became available in the queue I could grab the next chunk of data and queue it up ready for playing. Again, it only sort of worked. The track would buzz for 10 seconds, then play a second or 2, then go back to buzzing, then play some more. Sometimes it would play a whole 30-40 seconds perfectly, then the buzzing would start again. I fiddled with buffer sizes, buffer counts, filled my code with logging statements (the buffer queuing just seemed to stall while the buzzing took place). I tried to simplify it, removing lines of code, reorganizing until the code was slim and streamlined, I switched from vectors, to filling out static char* buffers. It made no difference.
I downloaded the source code of various apps, SuperTuxKart uses OpenAL and apparently the followed the same tutorial as me! In fact all the examples I could find had very similar code to the same tutorial, and my code looked pretty much the same.
This is the point I should have realized something else was at work here, in fact I did try upgrading ALSA but that changed nothing, so what did I do? I came up with a new design, one that had many benefits and might, just might have the side effect of solving the problem.
The problem with the previous attempts was I was loading and decoding the entire OGG file in one go. A decompressed, high quality OGG takes up a lot of memory, it's REALLY wasteful to decode the whole thing and keep it in memory. The other thing I had to be careful of was that multiple sources could play the same stream without an issue. I decided instead to load and store the compressed file data. Then create an OggDecoder class which each source gets an instance of that decompresses the data from memory on the fly. The benefits of this approach are huge, you don't hit the disk while playing, you keep memory usage down, and multiple sources can play from the same compressed data, and the code is pretty small too. So I finished, stood back and admired my work and pressed "compile and run". It worked! I was relieved. But just in case, I ran it a second time (it had *occasionally* worked before, it just wasn't consistent). You can guess what happened, the buzzing was back. Repeated runs left me with the same problem.
I was about to give up, about half way through this process I discovered cAudio which was basically where unintentional feature creep was pushing my code anyway (while trying to load an play a sound, I'd come up with a whole multiple song streaming solution with pluggable decoders!), so I figured I'd dump my code into the "deprecated" folder that I keep, and just use cAudio. Just as I was about to give up I found a forum post where someone had similar problems and they solved it by upgrading the OpenALSoft libraries. I gave it a try and lo and behold, it works!
I don't know why it works and didn't before, perhaps an OpenALSoft conflict with PA? Perhaps a bug in OpenALSoft? I dunno, and I don't care, if the problem occurs on another PC at least I know how to fix it.
The only regret is that I didn't realize it wasn't me earlier. I'd literally rewritten the code several times in different ways while comparing to code in other projects. Alarm bells should have rung earlier. Oh well.
Last weekend I decided it was time my game gained some sound. I'd just finished the game menu screen and figured that some music would make it seem a little more complete. In an attempt to follow the KISS principle I decided to keep it simple, I'd write a class that just plays an OGG file in 2D. No multiple sources, no bells and whistles, nothing fancy, just load an OGG and play it. A quick Google search turned up this gem of a tutorial, so I figured it was a 10 minute job. When the time came to do more, I'd look for a decent high-level library, or just steadily build on my simple base code but for now, I figured, following this tutorial would teach me a little OpenAL then I could move on.
And for a little while I was right. I wrote my class, loaded an OGG file and played it with OpenAL by loading it into a single buffer and binding the buffer to the source before calling alSourcePlay(). It worked!
...
For about 2 seconds. Then it crackled and went silent.
I assumed that the problem was the track I was playing was too long to be bound in a single buffer, and instead I figured I should break it into smaller buffers and feed it into the source to play. Possibly a bad assumption, I guess I should've tried playing a smaller sound to see if that was actually the case - but I was having fun, and queueing the buffers looked simple enough.
So I got to work, I decoded the OGG stream into a vector of vector<char>'s the idea being that as room became available in the queue I could grab the next chunk of data and queue it up ready for playing. Again, it only sort of worked. The track would buzz for 10 seconds, then play a second or 2, then go back to buzzing, then play some more. Sometimes it would play a whole 30-40 seconds perfectly, then the buzzing would start again. I fiddled with buffer sizes, buffer counts, filled my code with logging statements (the buffer queuing just seemed to stall while the buzzing took place). I tried to simplify it, removing lines of code, reorganizing until the code was slim and streamlined, I switched from vectors, to filling out static char* buffers. It made no difference.
I downloaded the source code of various apps, SuperTuxKart uses OpenAL and apparently the followed the same tutorial as me! In fact all the examples I could find had very similar code to the same tutorial, and my code looked pretty much the same.
This is the point I should have realized something else was at work here, in fact I did try upgrading ALSA but that changed nothing, so what did I do? I came up with a new design, one that had many benefits and might, just might have the side effect of solving the problem.
The problem with the previous attempts was I was loading and decoding the entire OGG file in one go. A decompressed, high quality OGG takes up a lot of memory, it's REALLY wasteful to decode the whole thing and keep it in memory. The other thing I had to be careful of was that multiple sources could play the same stream without an issue. I decided instead to load and store the compressed file data. Then create an OggDecoder class which each source gets an instance of that decompresses the data from memory on the fly. The benefits of this approach are huge, you don't hit the disk while playing, you keep memory usage down, and multiple sources can play from the same compressed data, and the code is pretty small too. So I finished, stood back and admired my work and pressed "compile and run". It worked! I was relieved. But just in case, I ran it a second time (it had *occasionally* worked before, it just wasn't consistent). You can guess what happened, the buzzing was back. Repeated runs left me with the same problem.
I was about to give up, about half way through this process I discovered cAudio which was basically where unintentional feature creep was pushing my code anyway (while trying to load an play a sound, I'd come up with a whole multiple song streaming solution with pluggable decoders!), so I figured I'd dump my code into the "deprecated" folder that I keep, and just use cAudio. Just as I was about to give up I found a forum post where someone had similar problems and they solved it by upgrading the OpenALSoft libraries. I gave it a try and lo and behold, it works!
I don't know why it works and didn't before, perhaps an OpenALSoft conflict with PA? Perhaps a bug in OpenALSoft? I dunno, and I don't care, if the problem occurs on another PC at least I know how to fix it.
The only regret is that I didn't realize it wasn't me earlier. I'd literally rewritten the code several times in different ways while comparing to code in other projects. Alarm bells should have rung earlier. Oh well.
Subscribe to:
Posts (Atom)