now it's possible to select the scheme file in the ifrontendfix a type about loading an image (iphone file system IS case senstive)
authorkoda
Thu, 17 Jun 2010 19:57:51 +0200
changeset 3513 f589230fa21b
parent 3512 6a8b5f313190
child 3514 59dbd31e9953
now it's possible to select the scheme file in the ifrontendfix a type about loading an image (iphone file system IS case senstive) add rotation for iphone build too make the ifrontend work again with 3.0 sdk reworked openalbridge following most of an old implementation by Smaxx and making it more modular -- now sources are limited but the memory extension and cleanup is todo nil'd many variables in engine that were causing intialization problems
cocoaTouch/DetailViewController.h
cocoaTouch/DetailViewController.m
cocoaTouch/GameConfigViewController.h
cocoaTouch/GameConfigViewController.m
cocoaTouch/GameSetup.m
cocoaTouch/GravesViewController.m
cocoaTouch/MainMenuViewController.m
cocoaTouch/MapConfigViewController.m
cocoaTouch/OverlayViewController.h
cocoaTouch/OverlayViewController.m
cocoaTouch/SchemeWeaponConfigViewController.h
cocoaTouch/SchemeWeaponConfigViewController.m
cocoaTouch/SingleSchemeViewController.m
cocoaTouch/SplitViewRootController.h
cocoaTouch/SplitViewRootController.m
cocoaTouch/VoicesViewController.m
cocoaTouch/otherSrc/CommodityFunctions.h
cocoaTouch/otherSrc/CommodityFunctions.m
hedgewars/uKeys.pas
hedgewars/uLand.pas
hedgewars/uLandObjects.pas
hedgewars/uLandTexture.pas
hedgewars/uMisc.pas
hedgewars/uStore.pas
hedgewars/uVisualGears.pas
hedgewars/uWorld.pas
misc/openalbridge/commands.c
misc/openalbridge/commands.h
misc/openalbridge/globals.h
misc/openalbridge/loaders.c
misc/openalbridge/loaders.h
misc/openalbridge/openalbridge.c
misc/openalbridge/openalbridge.h
misc/openalbridge/openalbridge_t.h
misc/openalbridge/wrappers.c
misc/openalbridge/wrappers.h
project_files/HedgewarsMobile/Hedgewars_Prefix.pch
--- a/cocoaTouch/DetailViewController.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/DetailViewController.h	Thu Jun 17 19:57:51 2010 +0200
@@ -13,7 +13,11 @@
 @class WeaponSettingsViewController;
 @class SchemeSettingsViewController;
 
-@interface DetailViewController : UITableViewController <UISplitViewControllerDelegate, UIPopoverControllerDelegate> {
+@interface DetailViewController : UITableViewController
+#if __IPHONE_3_2
+<UISplitViewControllerDelegate, UIPopoverControllerDelegate>
+#endif
+{
     NSArray *controllerNames;
     
     GeneralSettingsViewController *generalSettingsViewController;
--- a/cocoaTouch/DetailViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/DetailViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -128,6 +128,7 @@
     [[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" object:nil];
 }
 
+#if __IPHONE_3_2
 #pragma mark -
 #pragma mark splitview support
 -(void) splitViewController:(UISplitViewController *)svc popoverController:(UIPopoverController *)pc willPresentViewController:(UIViewController *)aViewController {
@@ -169,7 +170,7 @@
         self.navigationItem.rightBarButtonItem = nil;
 
 }
-
+#endif
 
 -(void) didReceiveMemoryWarning {
     // Releases the view if it doesn't have a superview.
--- a/cocoaTouch/GameConfigViewController.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/GameConfigViewController.h	Thu Jun 17 19:57:51 2010 +0200
@@ -10,14 +10,15 @@
 
 @class TeamConfigViewController;
 @class MapConfigViewController;
+@class SchemeWeaponConfigViewController;
 
 @interface GameConfigViewController : UIViewController {    
     UIViewController *activeController;
     MapConfigViewController *mapConfigViewController;
     TeamConfigViewController *teamConfigViewController;
+    SchemeWeaponConfigViewController *schemeWeaponConfigViewController;
 }
 
-
 -(IBAction) buttonPressed:(id) sender;
 -(IBAction) segmentPressed:(id) sender;
 -(void) startGame;
--- a/cocoaTouch/GameConfigViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/GameConfigViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -11,6 +11,7 @@
 #import "CommodityFunctions.h"
 #import "MapConfigViewController.h"
 #import "TeamConfigViewController.h"
+#import "SchemeWeaponConfigViewController.h"
 
 @implementation GameConfigViewController
 
@@ -31,7 +32,8 @@
                        withObject:nil
                        afterDelay:0.25];
             break;
-
+        default:
+            break;
     }
 }
 
@@ -43,23 +45,26 @@
             // this init here is just aestetic as this controller was already set up in viewDidLoad
             if (mapConfigViewController == nil) {
                 mapConfigViewController = [[MapConfigViewController alloc] initWithNibName:@"MapConfigViewController-iPhone" bundle:nil];
-                [mapConfigViewController viewWillAppear:NO];  
             }
             activeController = mapConfigViewController;
             break;
         case 1:
             if (teamConfigViewController == nil) {
                 teamConfigViewController = [[TeamConfigViewController alloc] initWithStyle:UITableViewStyleGrouped];
-                // this message is compulsory otherwise the team table won't be loaded at all
-                [teamConfigViewController viewWillAppear:NO];  
+                // this message is compulsory otherwise the table won't be loaded at all
             }
             activeController = teamConfigViewController;
             break;
         case 2:
-            
+            if (schemeWeaponConfigViewController == nil) {
+                schemeWeaponConfigViewController = [[SchemeWeaponConfigViewController alloc] initWithStyle:UITableViewStyleGrouped];
+            }
+            activeController = schemeWeaponConfigViewController;
             break;
     }
     
+    // this message is compulsory otherwise the table won't be loaded at all
+    [activeController viewWillAppear:NO];      
     [self.view addSubview:activeController.view];
 }
 
@@ -110,7 +115,10 @@
                                                                       mapConfigViewController.mapGenCommand,@"mapgen_command",
                                                                       mapConfigViewController.mazeSizeCommand,@"mazesize_command",
                                                                       mapConfigViewController.themeCommand,@"theme_command",
-                                                                      teamConfigViewController.listOfSelectedTeams,@"teams_list",nil];
+                                                                      teamConfigViewController.listOfSelectedTeams,@"teams_list",
+                                                                      schemeWeaponConfigViewController.selectedScheme,@"scheme",
+                                                                      schemeWeaponConfigViewController.selectedWeapon,@"weapon",
+                                                                      nil];
     [dict writeToFile:GAMECONFIG_FILE() atomically:YES];
     [dict release];
 
@@ -121,11 +129,18 @@
 
 -(void) viewDidLoad {
     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-        mapConfigViewController = [[MapConfigViewController alloc] initWithNibName:@"MapConfigViewController-iPad" bundle:nil];
-        teamConfigViewController = [[TeamConfigViewController alloc] initWithStyle:UITableViewStylePlain];
+        if (mapConfigViewController == nil)
+            mapConfigViewController = [[MapConfigViewController alloc] initWithNibName:@"MapConfigViewController-iPad" bundle:nil];
+        if (teamConfigViewController == nil)
+            teamConfigViewController = [[TeamConfigViewController alloc] initWithStyle:UITableViewStylePlain];
         teamConfigViewController.view.frame = CGRectMake(0, 224, 300, 500);
         teamConfigViewController.view.backgroundColor = [UIColor clearColor];
         [mapConfigViewController.view addSubview:teamConfigViewController.view];
+        if (schemeWeaponConfigViewController == nil)
+            schemeWeaponConfigViewController = [[SchemeWeaponConfigViewController alloc] initWithStyle:UITableViewStyleGrouped];
+        schemeWeaponConfigViewController.view.frame = CGRectMake(362, 224, 300, 500);
+        schemeWeaponConfigViewController.view.backgroundColor = [UIColor clearColor];
+        [mapConfigViewController.view addSubview:schemeWeaponConfigViewController.view];
     } else
         mapConfigViewController = [[MapConfigViewController alloc] initWithNibName:@"MapConfigViewController-iPhone" bundle:nil];
     activeController = mapConfigViewController;
@@ -138,6 +153,7 @@
 -(void) viewWillAppear:(BOOL)animated {
     [mapConfigViewController viewWillAppear:animated];
     [teamConfigViewController viewWillAppear:animated];
+    [schemeWeaponConfigViewController viewWillAppear:animated];
     // ADD other controllers here
      
     [super viewWillAppear:animated];
@@ -146,6 +162,7 @@
 -(void) viewDidAppear:(BOOL)animated {
     [mapConfigViewController viewDidAppear:animated];
     [teamConfigViewController viewDidAppear:animated];
+    [schemeWeaponConfigViewController viewDidAppear:animated];
     [super viewDidAppear:animated];
 }
 
@@ -157,24 +174,26 @@
         mapConfigViewController = nil;
     if (teamConfigViewController.view.superview == nil)
         teamConfigViewController = nil;
+    if (schemeWeaponConfigViewController.view.superview == nil)
+        schemeWeaponConfigViewController = nil;
     activeController = nil;
     MSG_MEMCLEAN();
 }
 
-
 -(void) viewDidUnload {
     activeController = nil;
     mapConfigViewController = nil;
     teamConfigViewController = nil;
+    schemeWeaponConfigViewController = nil;
     [super viewDidUnload];
     MSG_DIDUNLOAD();
 }
 
-
 -(void) dealloc {
     [activeController release];
     [mapConfigViewController release];
     [teamConfigViewController release];
+    [schemeWeaponConfigViewController release];
     [super dealloc];
 }
 
--- a/cocoaTouch/GameSetup.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/GameSetup.m	Thu Jun 17 19:57:51 2010 +0200
@@ -49,21 +49,7 @@
 }
 
 #pragma mark -
-#pragma mark Thread/Network relevant code
-// select one of GameSetup method and execute it in a seprate thread
--(void) startThread: (NSString *) selector {
-	SEL usage = NSSelectorFromString(selector);
-	[NSThread detachNewThreadSelector:usage toTarget:self withObject:nil];
-}
-
-// wrapper that computes the length of the message and then sends the command string
--(int) sendToEngine: (NSString *)string {
-	uint8_t length = [string length];
-	
-	SDLNet_TCP_Send(csd, &length , 1);
-	return SDLNet_TCP_Send(csd, [string UTF8String], length);
-}
-
+#pragma mark Provider functions
 // unpacks team data from the selected team.plist to a sequence of engine commands
 -(void) provideTeamData:(NSString *)teamName forHogs:(NSInteger) numberOfPlayingHogs withHealth:(NSInteger) initialHealth ofColor:(NSNumber *)teamColor {
     /*
@@ -152,12 +138,12 @@
 
 // unpacks scheme data from the selected scheme.plist to a sequence of engine commands
 -(NSInteger) provideScheme:(NSString *)schemeName {
-    NSString *schemePath = [[NSString alloc] initWithFormat:@"%@/%@.plist",SCHEMES_DIRECTORY(),schemeName];
+    NSString *schemePath = [[NSString alloc] initWithFormat:@"%@/%@",SCHEMES_DIRECTORY(),schemeName];
     NSArray *scheme = [[NSArray alloc] initWithContentsOfFile:schemePath];
     [schemePath release];
     int result = 0;
     int i = 0;
-    
+
     if ([[scheme objectAtIndex:i++] boolValue])
         result |= 0x01;
     if ([[scheme objectAtIndex:i++] boolValue])
@@ -223,7 +209,6 @@
     [self sendToEngine:minesNumber];
     [minesNumber release];
     
-
     NSString *dudMines = [[NSString alloc] initWithFormat:@"e$minedudpct %d",[[scheme objectAtIndex:i++] intValue]];
     [self sendToEngine:dudMines];
     [dudMines release];
@@ -236,6 +221,22 @@
     return result;
 }
 
+#pragma mark -
+#pragma mark Thread/Network relevant code
+// select one of GameSetup method and execute it in a seprate thread
+-(void) startThread: (NSString *) selector {
+	SEL usage = NSSelectorFromString(selector);
+	[NSThread detachNewThreadSelector:usage toTarget:self withObject:nil];
+}
+
+// wrapper that computes the length of the message and then sends the command string
+-(int) sendToEngine: (NSString *)string {
+	uint8_t length = [string length];
+	
+	SDLNet_TCP_Send(csd, &length , 1);
+	return SDLNet_TCP_Send(csd, [string UTF8String], length);
+}
+
 // method that handles net setup with engine and keeps connection alive
 -(void) engineProtocol {
 	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -292,7 +293,7 @@
 				[self sendToEngine:[self.gameConfig objectForKey:@"seed_command"]];
 				
                 // scheme (returns initial health)
-                NSInteger health = [self provideScheme:@"Scheme 0"];
+                NSInteger health = [self provideScheme:[self.gameConfig objectForKey:@"scheme"]];
 
 				// dimension of the map
 				[self sendToEngine:[self.gameConfig objectForKey:@"templatefilter_command"]];
--- a/cocoaTouch/GravesViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/GravesViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -48,17 +48,16 @@
 
 // Customize the appearance of table view cells.
 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    
     static NSString *CellIdentifier = @"Cell";
     
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     if (cell == nil)
         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
     
-    NSString *grave = [graveArray objectAtIndex:[indexPath row]];
+    NSString *grave = [self.graveArray objectAtIndex:[indexPath row]];
     cell.textLabel.text = [grave stringByDeletingPathExtension];
     
-    if ([grave isEqualToString:[teamDictionary objectForKey:@"grave"]]) {
+    if ([grave isEqualToString:[self.teamDictionary objectForKey:@"grave"]]) {
         cell.accessoryType = UITableViewCellAccessoryCheckmark;
         self.lastIndexPath = indexPath;
     } else {
--- a/cocoaTouch/MainMenuViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/MainMenuViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -75,7 +75,7 @@
     createTeamNamed(@"Pirates");
     createTeamNamed(@"Ninjas");
     
-    createSchemeNamed(@"Scheme 0");
+    createSchemeNamed(@"Default");
     
     // create settings.plist
     NSMutableDictionary *saveDict = [[NSMutableDictionary alloc] init];
--- a/cocoaTouch/MapConfigViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/MapConfigViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -120,7 +120,7 @@
     CGImageRelease(previewCGImage);
 
     // set the preview image (autoreleased) in the button and the maxhog label on the main thread to prevent a leak
-    [self performSelectorOnMainThread:@selector(setButtonImage:) withObject:[previewImage makeRoundCornersOfSize:CGSizeMake(12, 12)] waitUntilDone:NO];
+    [self performSelectorOnMainThread:@selector(setButtonImage:) withObject:[[previewImage retain] makeRoundCornersOfSize:CGSizeMake(12, 12)] waitUntilDone:NO];
     [self performSelectorOnMainThread:@selector(setLabelText:) withObject:[NSString stringWithFormat:@"%d", maxHogs] waitUntilDone:NO];
     
     // restore functionality of button and remove the spinning wheel on the main thread to prevent a leak
@@ -283,7 +283,7 @@
         // the % prevents a strange bug that occurs sporadically
         NSString *themeName = [self.themeArray objectAtIndex:row % [self.themeArray count]];
         cell.textLabel.text = themeName;
-        UIImage *image = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/Icon.png",THEMES_DIRECTORY(),themeName]];
+        UIImage *image = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/icon.png",THEMES_DIRECTORY(),themeName]];
         cell.imageView.image = image;
         [image release];
     } else {
--- a/cocoaTouch/OverlayViewController.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/OverlayViewController.h	Thu Jun 17 19:57:51 2010 +0200
@@ -12,7 +12,7 @@
 
 @interface OverlayViewController : UIViewController {
     NSTimer *dimTimer;
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
+#if __IPHONE_3_2
     UIPopoverController *popoverController;
 #else
     id popoverController;
--- a/cocoaTouch/OverlayViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/OverlayViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -59,19 +59,23 @@
             HW_setLandscape(YES);
             break;
         case UIDeviceOrientationPortrait:
-            sdlView.transform = CGAffineTransformMakeRotation(degreesToRadian(270));
-            self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
-            [self chatAppear];
-            HW_setLandscape(NO);
+            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+                sdlView.transform = CGAffineTransformMakeRotation(degreesToRadian(270));
+                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
+                [self chatAppear];
+                HW_setLandscape(NO);
+            }
             break;
         case UIDeviceOrientationPortraitUpsideDown:
-            sdlView.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
-            self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(180));
-            [self chatAppear];
-            HW_setLandscape(NO);
+            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+                sdlView.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
+                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(180));
+                [self chatAppear];
+                HW_setLandscape(NO);
+            }
             break;
         default:
-            NSLog(@"warning - Unknown rotation status");
+            DLog(@"Unknown rotation status");
             break;
     }
     self.view.frame = usefulRect;
@@ -126,19 +130,13 @@
                                                  name:@"dismissPopover"
                                                object:nil];
     
-    // need to split paths because iphone doesn't rotate (so we don't need to subscribe to any notification
-    // nor perform engine actions when rotating
-    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];	
-        [[NSNotificationCenter defaultCenter] addObserver:self
-                                                 selector:@selector(didRotate:)
-                                                     name:@"UIDeviceOrientationDidChangeNotification"
-                                                   object:nil];
-        
-        [self didRotate:nil];
-    } else 
-        self.view.transform = CGAffineTransformRotate(self.view.transform, (M_PI/2.0));
-    
+    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];	
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(didRotate:)
+                                                 name:@"UIDeviceOrientationDidChangeNotification"
+                                               object:nil];
+
+    //self.view.transform = CGAffineTransformRotate(self.view.transform, (M_PI/2.0)); 
 	[UIView beginAnimations:@"showing overlay" context:NULL];
 	[UIView setAnimationDuration:1];
 	self.view.alpha = 1;
@@ -239,7 +237,7 @@
     CGRect anchorForPopover;
     Class popoverControllerClass = NSClassFromString(@"UIPopoverController");
     if (popoverControllerClass) {
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
+#if __IPHONE_3_2
         if (popupMenu == nil) 
             popupMenu = [[PopoverMenuViewController alloc] initWithStyle:UITableViewStylePlain];
         popoverController = [[popoverControllerClass alloc] initWithContentViewController:popupMenu];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cocoaTouch/SchemeWeaponConfigViewController.h	Thu Jun 17 19:57:51 2010 +0200
@@ -0,0 +1,27 @@
+//
+//  SchemeWeaponConfigViewController.h
+//  Hedgewars
+//
+//  Created by Vittorio on 13/06/10.
+//  Copyright 2010 __MyCompanyName__. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+
+@interface SchemeWeaponConfigViewController : UITableViewController {
+    NSArray *listOfSchemes;
+    NSArray *listOfWeapons;
+    
+    NSIndexPath *lastIndexPath;
+    NSString *selectedScheme;
+    NSString *selectedWeapon;
+}
+
+@property (nonatomic, retain) NSArray *listOfSchemes;
+@property (nonatomic, retain) NSArray *listOfWeapons;
+@property (nonatomic,retain) NSIndexPath *lastIndexPath;
+@property (nonatomic,retain) NSString *selectedScheme;
+@property (nonatomic,retain) NSString *selectedWeapon;
+
+@end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cocoaTouch/SchemeWeaponConfigViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -0,0 +1,157 @@
+//
+//  SchemeWeaponConfigViewController.m
+//  Hedgewars
+//
+//  Created by Vittorio on 13/06/10.
+//  Copyright 2010 __MyCompanyName__. All rights reserved.
+//
+
+#import "SchemeWeaponConfigViewController.h"
+#import "CommodityFunctions.h"
+
+@implementation SchemeWeaponConfigViewController
+@synthesize listOfSchemes, listOfWeapons, lastIndexPath, selectedScheme, selectedWeapon;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+    [super viewDidLoad];
+
+    CGSize screenSize = [[UIScreen mainScreen] bounds].size;
+    self.view.frame = CGRectMake(0, 0, screenSize.height, screenSize.width - 44);
+
+    self.selectedScheme = @"Default.plist";
+    self.selectedWeapon = @"Default.plist";
+}
+
+-(void) viewWillAppear:(BOOL) animated {
+    [super viewWillAppear:animated];
+
+    NSArray *contentsOfDir = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:SCHEMES_DIRECTORY() error:NULL];
+    self.listOfSchemes = contentsOfDir;
+    
+    [self.tableView reloadData];
+}
+
+/*
+- (void)viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+}
+*/
+/*
+- (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+}
+*/
+/*
+- (void)viewDidDisappear:(BOOL)animated {
+    [super viewDidDisappear:animated];
+}
+*/
+
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+    return 2;
+}
+
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    if (section == 0) 
+        return [self.listOfSchemes count];
+    else
+        return [self.listOfWeapons count];
+}
+
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    static NSString *CellIdentifier = @"Cell";
+    NSInteger row = [indexPath row];
+    
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+    if (cell == nil) {
+        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+    }
+    
+    cell.accessoryType = UITableViewCellAccessoryNone;
+    if ([indexPath section] == 0) {
+        cell.textLabel.text = [[self.listOfSchemes objectAtIndex:row] stringByDeletingPathExtension];
+        if ([[self.listOfSchemes objectAtIndex:row] isEqualToString:self.selectedScheme]) {
+            cell.accessoryType = UITableViewCellAccessoryCheckmark;
+            self.lastIndexPath = indexPath;
+        }
+    } else {
+        cell.textLabel.text = [[self.listOfWeapons objectAtIndex:row] stringByDeletingPathExtension];
+        if ([[self.listOfWeapons objectAtIndex:row] isEqualToString:self.selectedWeapon]) {
+            cell.accessoryType = UITableViewCellAccessoryCheckmark;
+            self.lastIndexPath = indexPath;
+        }
+    }
+
+    return cell;
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    int newRow = [indexPath row];
+    int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+    
+    if (newRow != oldRow) {
+        //TODO: this code works only for a single section table
+        UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
+        newCell.accessoryType = UITableViewCellAccessoryCheckmark;
+        UITableViewCell *oldCell = [aTableView cellForRowAtIndexPath:lastIndexPath];
+        oldCell.accessoryType = UITableViewCellAccessoryNone;
+        self.lastIndexPath = indexPath;
+        self.selectedScheme = [self.listOfSchemes objectAtIndex:newRow];
+        [aTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+    }
+    [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger) section {
+    if (section == 0) {
+        return NSLocalizedString(@"Schemes",@"");
+    } else {
+        return NSLocalizedString(@"Weapons",@"");;
+    }
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    // Relinquish ownership any cached data, images, etc that aren't in use.
+}
+
+-(void) viewDidUnload {
+    self.listOfSchemes = nil;
+    self.listOfWeapons = nil;
+    self.lastIndexPath = nil;
+    self.selectedScheme = nil;
+    self.selectedWeapon = nil;
+    MSG_DIDUNLOAD();
+}
+
+
+-(void) dealloc {
+    [listOfSchemes release];
+    [listOfWeapons release];
+    [lastIndexPath release];
+    [selectedScheme release];
+    [selectedWeapon release];
+    [super dealloc];
+}
+
+
+@end
+
--- a/cocoaTouch/SingleSchemeViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/SingleSchemeViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -103,6 +103,8 @@
     self.schemeArray = scheme;
     [scheme release];
 	[schemeFile release];
+    
+    [self.tableView reloadData];
 }
 
 // save to file
--- a/cocoaTouch/SplitViewRootController.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/SplitViewRootController.h	Thu Jun 17 19:57:51 2010 +0200
@@ -9,7 +9,7 @@
 #import <UIKit/UIKit.h>
 
 @class DetailViewController;
-@interface SplitViewRootController : UIViewController  <UISplitViewControllerDelegate, UIPopoverControllerDelegate>{
+@interface SplitViewRootController: UIViewController {
     DetailViewController *detailViewController;
 }
 
--- a/cocoaTouch/SplitViewRootController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/SplitViewRootController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -40,7 +40,7 @@
         
     Class splitViewControllerClass = NSClassFromString(@"UISplitViewController");
     if (splitViewControllerClass) {
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
+#if __IPHONE_3_2
         UISplitViewController *splitViewRootController = [[UISplitViewController alloc] init];
         //splitViewRootController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;        
         splitViewRootController.view.frame = CGRectMake(0, 0, rect.size.height, rect.size.width);
--- a/cocoaTouch/VoicesViewController.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/VoicesViewController.m	Thu Jun 17 19:57:51 2010 +0200
@@ -26,12 +26,7 @@
     [super viewDidLoad];
     srandom(time(NULL));
 
-    openal_init(1);
-    voiceBeingPlayed = -1;
-
-    // load all the voices names and store them into voiceArray
-    NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:VOICES_DIRECTORY() error:NULL];
-    self.voiceArray = array;
+    openal_init(20);
 }
 
 - (void)viewWillAppear:(BOOL)animated {
@@ -39,6 +34,11 @@
     
     // this moves the tableview to the top
     [self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+    voiceBeingPlayed = -1;
+
+    // load all the voices names and store them into voiceArray
+    NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:VOICES_DIRECTORY() error:NULL];
+    self.voiceArray = array;
 }
 
 /*
@@ -50,17 +50,11 @@
 - (void)viewWillDisappear:(BOOL)animated {
     [super viewWillDisappear:animated];
     if(voiceBeingPlayed >= 0) {
-        openal_freesound(voiceBeingPlayed);
+        openal_stopsound(voiceBeingPlayed);
         voiceBeingPlayed = -1;
     }
 }
 
-/*
-- (void)viewDidDisappear:(BOOL)animated {
-    [super viewDidDisappear:animated];
-}
-*/
-
 
 #pragma mark -
 #pragma mark Table view data source
@@ -73,7 +67,7 @@
 }
 
 // Customize the appearance of table view cells.
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     
     static NSString *CellIdentifier = @"Cell";
     
@@ -96,45 +90,6 @@
 }
 
 
-/*
-// Override to support conditional editing of the table view.
-- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
-    // Return NO if you do not want the specified item to be editable.
-    return YES;
-}
-*/
-
-
-/*
-// Override to support editing the table view.
-- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
-    
-    if (editingStyle == UITableViewCellEditingStyleDelete) {
-        // Delete the row from the data source
-        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
-    }   
-    else if (editingStyle == UITableViewCellEditingStyleInsert) {
-        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
-    }   
-}
-*/
-
-
-/*
-// Override to support rearranging the table view.
-- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
-}
-*/
-
-
-/*
-// Override to support conditional rearranging of the table view.
-- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
-    // Return NO if you do not want the item to be re-orderable.
-    return YES;
-}
-*/
-
 #pragma mark -
 #pragma mark Table view delegate
 -(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
@@ -155,7 +110,6 @@
     
     if (voiceBeingPlayed >= 0) {
         openal_stopsound(voiceBeingPlayed);
-        openal_freesound(voiceBeingPlayed);
         voiceBeingPlayed = -1;
     }
     
@@ -174,9 +128,6 @@
 #pragma mark -
 #pragma mark Memory management
 -(void) didReceiveMemoryWarning {
-    openal_stopsound(voiceBeingPlayed);
-    openal_freesound(voiceBeingPlayed);
-    voiceBeingPlayed = -1;
     // Releases the view if it doesn't have a superview.
     [super didReceiveMemoryWarning];
     // Relinquish ownership any cached data, images, etc that aren't in use.
@@ -202,4 +153,3 @@
 
 @end
 
-
--- a/cocoaTouch/otherSrc/CommodityFunctions.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/otherSrc/CommodityFunctions.h	Thu Jun 17 19:57:51 2010 +0200
@@ -44,11 +44,3 @@
 void popError (const char *title, const char *message);
 void print_free_memory ();
 
-#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_3_2
-typedef enum {
-    UIUserInterfaceIdiomPhone,           // iPhone and iPod touch style UI
-    UIUserInterfaceIdiomPad,             // iPad style UI
-} UIUserInterfaceIdiom;
-#define UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPhone
-#endif // ifndef __IPHONE_3_2
-
--- a/cocoaTouch/otherSrc/CommodityFunctions.m	Thu Jun 17 11:42:23 2010 -0400
+++ b/cocoaTouch/otherSrc/CommodityFunctions.m	Thu Jun 17 19:57:51 2010 +0200
@@ -93,8 +93,8 @@
     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
         return YES;
     else
-        return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
-
+        return (interfaceOrientation == UIInterfaceOrientationLandscapeRight) ||
+               (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);  
 }
 
 NSInteger randomPort () {
--- a/hedgewars/uKeys.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uKeys.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -423,7 +423,9 @@
 procedure ControllerInit;
 var i, j: Integer;
 begin
+{$IFNDEF IPHONEOS}
 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+{$ENDIF}
 
 ControllerEnabled:= 0;
 ControllerNumControllers:= SDL_NumJoysticks();
--- a/hedgewars/uLand.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uLand.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -1177,6 +1177,7 @@
     end;
     if (tmpsurf <> nil) then 
         SDL_FreeSurface(tmpsurf);
+    tmpsurf:= nil;
 end;
 
 procedure LoadMap;
--- a/hedgewars/uLandObjects.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uLandObjects.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -536,6 +536,8 @@
             SDL_FreeSurface(ThemeObjects.objs[i].Surf);
         if SprayObjects.objs[i].Surf <> nil then
             SDL_FreeSurface(SprayObjects.objs[i].Surf);
+        ThemeObjects.objs[i].Surf:= nil;
+        SprayObjects.objs[i].Surf:= nil;
     end;
 end;
 
--- a/hedgewars/uLandTexture.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uLandTexture.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -137,8 +137,9 @@
                 tex:= nil;
             end;
 
-if LandBackSurface <> nil then
-    SDL_FreeSurface(LandBackSurface);
+    if LandBackSurface <> nil then
+        SDL_FreeSurface(LandBackSurface);
+    LandBackSurface:= nil;
 end;
 
 end.
--- a/hedgewars/uMisc.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uMisc.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -506,13 +506,16 @@
 
 procedure FreeTexture(tex: PTexture);
 begin
-if tex <> nil then
+    if tex <> nil then
     begin
-    if tex^.NextTexture <> nil then tex^.NextTexture^.PrevTexture:= tex^.PrevTexture;
-    if tex^.PrevTexture <> nil then tex^.PrevTexture^.NextTexture:= tex^.NextTexture
-    else TextureList:= tex^.NextTexture;
-    glDeleteTextures(1, @tex^.id);
-    Dispose(tex)
+        if tex^.NextTexture <> nil then 
+            tex^.NextTexture^.PrevTexture:= tex^.PrevTexture;
+        if tex^.PrevTexture <> nil then 
+            tex^.PrevTexture^.NextTexture:= tex^.NextTexture
+        else 
+            TextureList:= tex^.NextTexture;
+        glDeleteTextures(1, @tex^.id);
+        Dispose(tex);
     end
 end;
 
--- a/hedgewars/uStore.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uStore.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -250,6 +250,7 @@
         TryDo(flagsurf <> nil, 'Failed to load flag "' + Flag + '" as well as the default flag', true);
         copyToXY(flagsurf, texsurf, 2, 2);
         SDL_FreeSurface(flagsurf);
+        flagsurf:= nil;
         
         // restore black border pixels inside the flag
         PLongwordArray(texsurf^.pixels)^[32 * 2 +  2]:= cNearBlackColor;
@@ -259,7 +260,6 @@
 
         FlagTex:= Surface2Tex(texsurf, false);
         SDL_FreeSurface(texsurf);
-        texsurf:= nil;
 
         dec(drY, r.h + 2);
         DrawHealthY:= drY;
@@ -274,25 +274,27 @@
                             texsurf:= LoadImage(Pathz[ptHats] + '/Reserved/' + Copy(Hat,9,Length(s)-8), ifNone)
                         else
                             texsurf:= LoadImage(Pathz[ptHats] + '/' + Hat, ifNone);
-                        if texsurf <> nil then
+                            if texsurf <> nil then
                             begin
-                            HatTex:= Surface2Tex(texsurf, true);
-                            SDL_FreeSurface(texsurf)
-                            end
+                                HatTex:= Surface2Tex(texsurf, true);
+                                SDL_FreeSurface(texsurf)
+                            end;
+                            texsurf:= nil;
                         end
                     end;
         end;
     MissionIcons:= LoadImage(Pathz[ptGraphics] + '/missions', ifCritical);
     iconsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, 28, 28, 32, RMask, GMask, BMask, AMask);
-    if iconsurf <> nil then
+        if iconsurf <> nil then
         begin
-        r.x:= 0;
-        r.y:= 0;
-        r.w:= 28;
-        r.h:= 28;
-        DrawRoundRect(@r, cWhiteColor, cNearBlackColor, iconsurf, true);
-        ropeIconTex:= Surface2Tex(iconsurf, false);
-        SDL_FreeSurface(iconsurf)
+            r.x:= 0;
+            r.y:= 0;
+            r.w:= 28;
+            r.h:= 28;
+            DrawRoundRect(@r, cWhiteColor, cNearBlackColor, iconsurf, true);
+            ropeIconTex:= Surface2Tex(iconsurf, false);
+            SDL_FreeSurface(iconsurf);
+            iconsurf:= nil;
         end;
     end;
 
@@ -816,8 +818,10 @@
     for ii:= Low(TSprite) to High(TSprite) do
     begin
         FreeTexture(SpritesData[ii].Texture);
+        SpritesData[ii].Texture:= nil;
         if SpritesData[ii].Surface <> nil then
-            SDL_FreeSurface(SpritesData[ii].Surface)
+            SDL_FreeSurface(SpritesData[ii].Surface);
+        SpritesData[ii].Surface:= nil;
     end;
     SDL_FreeSurface(MissionIcons);
     FreeTexture(ropeIconTex);
--- a/hedgewars/uVisualGears.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uVisualGears.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -327,14 +327,15 @@
 
 procedure DeleteVisualGear(Gear: PVisualGear);
 begin
-if Gear^.Tex <> nil then
-    FreeTexture(Gear^.Tex);
+    if Gear^.Tex <> nil then
+        FreeTexture(Gear^.Tex);
+    Gear^.Tex:= nil;
 
-if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
-if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
-   else VisualGearsList:= Gear^.NextGear;
+    if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
+    if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
+    else VisualGearsList:= Gear^.NextGear;
 
-Dispose(Gear)
+    Dispose(Gear);
 end;
 
 procedure ProcessVisualGears(Steps: Longword);
--- a/hedgewars/uWorld.pas	Thu Jun 17 11:42:23 2010 -0400
+++ b/hedgewars/uWorld.pas	Thu Jun 17 19:57:51 2010 +0200
@@ -872,7 +872,10 @@
    if t < 10 then s:= '0' + s;
    s:= inttostr(i div 60) + ':' + s;
    
-   if timeTexture <> nil then FreeTexture(timeTexture);
+   if timeTexture <> nil then
+        FreeTexture(timeTexture);
+    timeTexture:= nil;
+    
    tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
    tmpSurface:= doSurfaceConversion(tmpSurface);
    timeTexture:= Surface2Tex(tmpSurface, false);
@@ -890,7 +893,9 @@
       Frames:= 0;
       CountTicks:= 0;
       s:= inttostr(FPS) + ' fps';
-      if fpsTexture <> nil then FreeTexture(fpsTexture);
+      if fpsTexture <> nil then
+        FreeTexture(fpsTexture);
+    fpsTexture:= nil;
       tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
       tmpSurface:= doSurfaceConversion(tmpSurface);
       fpsTexture:= Surface2Tex(tmpSurface, false);
@@ -981,14 +986,16 @@
 procedure AddCaption(s: shortstring; Color: Longword; Group: TCapGroup);
 begin
 //if Group in [capgrpGameState] then WriteLnToConsole(s);
-if Captions[Group].Tex <> nil then FreeTexture(Captions[Group].Tex);
-
-Captions[Group].Tex:= RenderStringTex(s, Color, fntBig);
+    if Captions[Group].Tex <> nil then 
+        FreeTexture(Captions[Group].Tex);
+    Captions[Group].Tex:= nil;
 
-case Group of
-    capgrpGameState: Captions[Group].EndTime:= RealTicks + 2200
+    Captions[Group].Tex:= RenderStringTex(s, Color, fntBig);
+
+    case Group of
+        capgrpGameState: Captions[Group].EndTime:= RealTicks + 2200
     else
-    Captions[Group].EndTime:= RealTicks + 1400 + LongWord(Captions[Group].Tex^.w) * 3;
+        Captions[Group].EndTime:= RealTicks + 1400 + LongWord(Captions[Group].Tex^.w) * 3;
     end;
 end;
 
@@ -1096,7 +1103,9 @@
 
 if time = 0 then time:= 5000;
 missionTimer:= time;
-if missionTex <> nil then FreeTexture(missionTex);
+if missionTex <> nil then 
+    FreeTexture(missionTex);
+missionTex:= nil;
 
 if icon > -1 then
     begin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/openalbridge/commands.c	Thu Jun 17 19:57:51 2010 +0200
@@ -0,0 +1,224 @@
+/*
+ *  commands.c
+ *  Hedgewars
+ *
+ *  Created by Vittorio on 13/06/10.
+ *  Copyright 2010 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include "commands.h"
+#include "wrappers.h"
+
+ALfloat old_gain;
+extern ALuint *Sources;
+extern ALuint cache_size, cache_index, sources_number;
+extern ALboolean instances_number;
+extern al_sound_t *the_sounds;
+
+void openal_pausesound (uint32_t index) {
+    if (openal_ready() == AL_TRUE && index < cache_size)
+        alSourcePause(Sources[the_sounds[index].source_index]);
+}
+
+
+void openal_stopsound (uint32_t index) {
+    if (openal_ready() == AL_TRUE && index < cache_size)
+        alSourceStop(Sources[the_sounds[index].source_index]);
+}
+
+
+void openal_playsound (unsigned int index) {
+    ALboolean needsSource = AL_TRUE;
+    ALfloat SourcePosition[] = { 0.0, 0.0, 0.0 };
+    ALfloat SourceVelocity[] = { 0.0, 0.0, 0.0 };
+    ALint state;
+    int i, j;
+    
+    if (openal_ready() == AL_TRUE && index < cache_size) {
+        // check if sound has already a source
+        if (the_sounds[index].source_index != -1) {
+            // it has a source, check it's not playing
+            alGetSourcei(Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state);
+            if (state != AL_PLAYING && state != AL_PAUSED) { 	 
+                // it is not being played, so we can use it safely
+	            needsSource = AL_FALSE; 		 
+            }
+            // else it is being played, so we have to allocate a new source for this buffer
+        }
+        
+        if (needsSource) {
+#ifdef DEBUG
+            fprintf(stderr,"(Bridge Debug) - looking for a source for sound %d\n", index);
+#endif
+            for (i = 0; i < sources_number; i++) {
+                // let's iterate on Sources until we find a source that is not playing
+                alGetSourcei(Sources[i], AL_SOURCE_STATE, &state); 	 
+                if (state != AL_PLAYING && state != AL_PAUSED) {
+                    // let's iterate on the_sounds until we find the sound using that source
+                    for (j = 0; j < cache_size; j++) {
+                        if (the_sounds[j].source_index == i) {
+                            the_sounds[j].source_index = -1;
+                            break;
+                        }
+                    }
+                    // here we know that no-one is using that source so we can use it
+                    break;
+                }
+            }
+            
+            if (i == sources_number) {
+                // this means all sources are busy
+            }
+            
+            // set source properties that it will use when it's in playback
+            alSourcei (Sources[i], AL_BUFFER,   the_sounds[index].buffer);
+            alSourcef (Sources[i], AL_PITCH,    1.0f);
+            alSourcef (Sources[i], AL_GAIN,     1.0f);
+            alSourcefv(Sources[i], AL_POSITION, SourcePosition);
+            alSourcefv(Sources[i], AL_VELOCITY, SourceVelocity);
+            alSourcei (Sources[i], AL_LOOPING,  0);
+            
+            if (AL_NO_ERROR != alGetError()) {
+                fprintf(stderr,"(Bridge ERROR) - failed to set Source properties\n");
+                return;
+            }
+            the_sounds[index].source_index = i;
+        }
+        
+        alSourcePlay(Sources[the_sounds[index].source_index]);
+        
+        if (AL_NO_ERROR != alGetError()) {
+            fprintf(stderr,"(Bridge Warning) - failed to play sound %d\n", index);
+            return;
+        }
+        
+        the_sounds[index].stats++;
+    }
+}
+
+void openal_toggleloop (uint32_t index) {
+    ALint loop;
+
+    if (openal_ready() == AL_TRUE && index < cache_size) {
+        alGetSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, &loop);
+        alSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, !((uint8_t) loop) & 0x00000001);
+    }
+}
+
+
+void openal_setvolume (uint32_t index, float gain) {
+    if (openal_ready() == AL_TRUE && index < cache_size)
+        alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, gain);
+}
+
+
+void openal_setglobalvolume (float gain) {
+    if (openal_ready() == AL_TRUE)
+        alListenerf (AL_GAIN, gain);
+}
+
+void openal_togglemute () {
+    ALfloat gain;
+
+    if (openal_ready() == AL_TRUE) {
+        alGetListenerf (AL_GAIN, &gain);
+        if (gain > 0) {
+            old_gain = gain;
+            gain = 0;
+        } else
+            gain = old_gain;
+
+        alListenerf (AL_GAIN, gain);
+    }
+}
+
+// Fade in or out by calling a helper thread
+void openal_fade (uint32_t index, uint16_t quantity, al_fade_t direction) {
+#ifndef _WIN32
+    pthread_t thread;
+#else
+    HANDLE Thread;
+#endif
+    fade_t *fade;
+
+    if (openal_ready() == AL_TRUE && index < cache_size) {
+        fade = (fade_t*) Malloc(sizeof(fade_t));
+        fade->index = index;
+        fade->quantity = quantity;
+        fade->type = direction;
+
+#ifndef _WIN32
+        pthread_create(&thread, NULL, (void *)helper_fade, (void *)fade);
+        pthread_detach(thread);
+#else
+        Thread = (HANDLE) _beginthread((void *)helper_fade, 0, (void *)fade);
+#endif
+    }
+}
+
+void openal_setposition (uint32_t index, float x, float y, float z) {
+    if (openal_ready() == AL_TRUE && index < cache_size)
+        alSource3f(Sources[the_sounds[index].source_index], AL_POSITION, x, y, z);;
+}
+
+void helper_fade(void *tmp) {
+    ALfloat gain;
+    ALfloat target_gain;
+    fade_t *fade;
+    uint32_t index;
+    uint16_t quantity;
+    al_fade_t type;
+
+    fade = tmp;
+    index = fade->index;
+    quantity = fade->quantity;
+    type = fade->type;
+    free (fade);
+
+    if (type == AL_FADE_IN) {
+#ifdef DEBUG
+        fprintf(stderr,"(Bridge Info) - Fade-in in progress [index %d quantity %d]", index, quantity);
+#endif
+
+        // save the volume desired after the fade
+        alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
+        if (target_gain > 1.0f || target_gain <= 0.0f)
+            target_gain = 1.0f;
+
+        for (gain = 0.0f ; gain <= target_gain; gain += (float) quantity/10000) {
+#ifdef TRACE
+            fprintf(stderr,"(Bridge Debug) - Fade-in set gain to %f\n", gain);
+#endif
+            alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
+            usleep(10000);
+        }
+    } else {
+        alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
+
+        for (gain = target_gain; gain >= 0.00f; gain -= (float) quantity/10000) {
+#ifdef TRACE
+            fprintf(stderr,"(Bridge Debug) - Fade-out set gain to %f\n", gain);
+#endif
+            alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
+            usleep(10000);
+        }
+
+        if (AL_NO_ERROR != alGetError())
+            fprintf(stderr,"(Bridge Warning) - Failed to set fade-out effect\n");
+
+        // stop that sound and reset its volume
+        alSourceStop (Sources[the_sounds[index].source_index]);
+        alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, target_gain);
+    }
+
+    if (AL_NO_ERROR != alGetError())
+        fprintf(stderr,"(Bridge Warning) - Failed to set fade effect\n");
+
+#ifndef _WIN32
+    pthread_exit(NULL);
+#else
+    _endthread();
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/openalbridge/commands.h	Thu Jun 17 19:57:51 2010 +0200
@@ -0,0 +1,55 @@
+/*
+ *  commands.h
+ *  Hedgewars
+ *
+ *  Created by Vittorio on 13/06/10.
+ *  Copyright 2010 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef _OALB_COMMANDS_H
+#define _OALB_COMMANDS_H
+
+#include "openalbridge_t.h"
+#include "openalbridge.h"
+
+
+#define openal_fadein(x,y)          openal_fade(x,y,AL_FADE_IN)
+#define openal_fadeout(x,y)         openal_fade(x,y,AL_FADE_OUT)
+#define openal_playsound_loop(x,y)  openal_playsound(x)  \
+                                        if (y != 0)  \
+                                        openal_toggleloop(x);
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif
+    
+    // play, pause, stop a single sound source
+    void openal_pausesound        (unsigned int index);
+    void openal_stopsound         (unsigned int index);
+    
+    // play a sound and set whether it should loop or not (0/1)
+    void openal_playsound         (unsigned int index);
+    
+    void openal_freesound         (unsigned int index);
+    
+    // set or unset the looping property for a sound source
+    void openal_toggleloop        (unsigned int index);
+    
+    // set position and volume of a sound source
+    void openal_setposition       (unsigned int index, float x, float y, float z);
+    void openal_setvolume         (unsigned int index, float gain);
+    
+    // set volume for all sounds (gain interval is [0-1])
+    void openal_setglobalvolume   (float gain);
+    
+    // mute or unmute all sounds
+    void openal_togglemute        (void);
+    
+    // fade effect,
+    void openal_fade              (unsigned int index, unsigned short int quantity, al_fade_t direction);
+    
+#ifdef __CPLUSPLUS
+}
+#endif
+
+#endif /*_OALB_COMMANDS_H*/
\ No newline at end of file
--- a/misc/openalbridge/globals.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/globals.h	Thu Jun 17 19:57:51 2010 +0200
@@ -31,13 +31,6 @@
 #endif
 
 
-// control debug verbosity
-#ifdef TRACE
-#ifndef DEBUG
-#define DEBUG
-#endif
-#endif
-
 // 1.0 02/03/10 - Defines cross-platform sleep, usleep, etc. [Wu Yongwei]
 #ifndef _SLEEP_H
 #define _SLEEP_H
@@ -92,7 +85,7 @@
 #define ENDIAN_BIG_16(x)    x
 #endif
 
-/*file format defines*/
+/* file format defines */
 #define OGG_FILE_FORMAT         0x4F676753
 #define WAV_FILE_FORMAT         0x52494646
 #define WAV_HEADER_SUBCHUNK2ID  0x64617461
--- a/misc/openalbridge/loaders.c	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/loaders.c	Thu Jun 17 19:57:51 2010 +0200
@@ -22,7 +22,7 @@
 #include "openalbridge_t.h"
 
 
-int load_wavpcm (const char *filename, ALenum *format, char ** data, ALsizei *bitsize, ALsizei *freq) {
+int load_wavpcm (const char *filename, ALenum *format, char **data, ALsizei *bitsize, ALsizei *freq) {
     WAV_header_t WAVHeader;
     FILE *wavfile;
     int32_t t;
@@ -80,7 +80,7 @@
 
         if (t <= 0) {
             // eof
-            fprintf(stderr,"(Bridge Error) - wrong WAV header");
+            fprintf(stderr,"(Bridge Error) - wrong WAV header\n");
             return -1;
         }
     } while (1);
@@ -102,7 +102,7 @@
     fclose(wavfile);
 
 #ifdef DEBUG
-    fprintf(stderr,"(Bridge Info) - WAV data loaded");
+    fprintf(stderr,"(Bridge Info) - WAV data loaded\n");
 #endif
 
     /*set parameters for OpenAL*/
@@ -114,7 +114,7 @@
             if (ENDIAN_LITTLE_16(WAVHeader.BitsPerSample) == 16)
                 *format = AL_FORMAT_MONO16;
             else {
-                fprintf(stderr,"(Bridge Error) - wrong WAV header [bitsample value]");
+                fprintf(stderr,"(Bridge Error) - wrong WAV header [bitsample value]\n");
                 return -2;
             }
         }
@@ -126,12 +126,12 @@
                 if (ENDIAN_LITTLE_16(WAVHeader.BitsPerSample) == 16)
                     *format = AL_FORMAT_STEREO16;
                 else {
-                    fprintf(stderr,"(Bridge Error) - wrong WAV header [bitsample value]");
+                    fprintf(stderr,"(Bridge Error) - wrong WAV header [bitsample value]\n");
                     return -2;
                 }
             }
         } else {
-            fprintf(stderr,"(Bridge Error) - wrong WAV header [format value]");
+            fprintf(stderr,"(Bridge Error) - wrong WAV header [format value]\n");
             return -2;
         }
     }
@@ -164,7 +164,7 @@
     oggFile = Fopen(filename, "rb");
     result = ov_open_callbacks(oggFile, &oggStream, NULL, 0, OV_CALLBACKS_DEFAULT);
     if (result < 0) {
-        fprintf(stderr,"(Bridge Error) - ov_open_callbacks() failed with %X", result);
+        fprintf(stderr,"(Bridge Error) - ov_open_callbacks() failed with %X\n", result);
         ov_clear(&oggStream);
         return -1;
     }
@@ -199,7 +199,7 @@
         if (vorbisInfo->channels == 2)
             *format = AL_FORMAT_STEREO16;
         else {
-            fprintf(stderr,"(Bridge Error) - wrong OGG header [channel %d]", vorbisInfo->channels);
+            fprintf(stderr,"(Bridge Error) - wrong OGG header [channel %d]\n", vorbisInfo->channels);
             ov_clear(&oggStream);
             return -2;
         }
@@ -220,7 +220,7 @@
             if (result == 0)
                 break;
             else {
-                fprintf(stderr,"(Bridge Error) - End of file from OGG stream");
+                fprintf(stderr,"(Bridge Error) - End of file from OGG stream\n");
                 ov_clear(&oggStream);
                 return -3;
             }
--- a/misc/openalbridge/loaders.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/loaders.h	Thu Jun 17 19:57:51 2010 +0200
@@ -16,11 +16,11 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
+#include "globals.h"
+
 #ifndef _OALB_LOADERS_H
 #define _OALB_LOADERS_H
 
-#include "globals.h"
-
 int load_wavpcm     (const char *filename, ALenum *format, char **data, ALsizei *bitsize, ALsizei *freq);
 int load_oggvorbis  (const char *filename, ALenum *format, char **data, ALsizei *bitsize, ALsizei *freq);
 
--- a/misc/openalbridge/openalbridge.c	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/openalbridge.c	Thu Jun 17 19:57:51 2010 +0200
@@ -22,187 +22,200 @@
 #include "alc.h"
 #include "wrappers.h"
 #include "loaders.h"
-
+#include "string.h"
 
-/*Sources are points emitting sound*/
+// Sources are points emitting sound, their number is limited, but a single source can play many buffers
+// Buffers hold sound data and are unlimited
 ALuint *Sources;
-/*Buffers hold sound data*/
-ALuint *Buffers;
-/*index for Sources and Buffers*/
-ALuint globalindex, globalsize, increment;
+ALuint cache_size, cache_index, sources_number;
+ALboolean instances_number;
+al_sound_t *the_sounds;
+ALint cache_pointer;
 
-ALboolean isBridgeReady = AL_FALSE;
-ALfloat old_gain;
-
+// Initialize an OpenAL contex and allocate memory space for data and buffers
+// It can be called twice to increase the cache size
 int openal_init (int memorysize) {
-    /*Initialize an OpenAL contex and allocate memory space for data and buffers*/
     ALCcontext *context;
     ALCdevice *device;
+    int i;
+        
+    // reuse old context and resize the existing 
+    if (openal_ready() == AL_TRUE) {
+        cache_size += memorysize;
+        fprintf(stderr,"(Bridge Info) - already initialized, resizing cache to %d\n", cache_size);
+        the_sounds = (al_sound_t *)Realloc (the_sounds, sizeof(al_sound_t) * cache_size);
+        for (i = cache_size - memorysize; i < cache_size; i++) {
+            the_sounds[i].filename = NULL;
+            the_sounds[i].buffer = -1;
+            the_sounds[i].source_index = -1;
+            the_sounds[i].stats = 0;
+        }
+        instances_number++;
+        return AL_TRUE;
+    }
+    
+    cache_pointer = 0;
+    instances_number++;
     
     // set the memory dimentsion and the increment width when reallocating
     if (memorysize <= 0)
-        globalsize = 50;
+        cache_size = 50;
     else
-        globalsize = memorysize;
-    increment = globalsize;
-    
-    // reuse old context but keep the new value for increment
-    if (isBridgeReady == AL_TRUE) {
-        fprintf(stderr,"(Bridge Warning) - already initialized");
-        return 0;
-    }
-    
+        cache_size = memorysize;
+
     // open hardware device if present
     device = alcOpenDevice(NULL);
-    
+    sources_number = 16;
     if (device == NULL) {
-        fprintf(stderr,"(Bridge Warning) - failed to open sound device, using software renderer");
+        fprintf(stderr,"(Bridge Warning) - failed to open sound device, using software renderer\n");
         device = alcOpenDevice("Generic Software");
+        sources_number = 32;
         if (device == NULL) {
-            fprintf(stderr,"(Bridge Error) - failed to open sound software device, sound will be disabled");
+            fprintf(stderr,"(Bridge ERROR) - failed to start software renderer, sound will be disabled\n");
             return -1;
         }
     }
-    
-    fprintf(stderr,"(Bridge Info) - Output device: %s", alcGetString(device, ALC_DEVICE_SPECIFIER));
-    
+
+    fprintf(stderr,"(Bridge Info) - output device: %s\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
+
     context = alcCreateContext(device, NULL);
     alcMakeContextCurrent(context);
     alcProcessContext(context);
-    
+
     if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge Error) - Failed to create a new contex");
+        fprintf(stderr,"(Bridge ERROR) - Failed to create a new contex\n");
         alcMakeContextCurrent(NULL);
         alcDestroyContext(context);
         alcCloseDevice(device);
         return -2;
     }
-    
-    // allocate memory space for buffers and sources
-    Buffers = (ALuint*) Malloc(sizeof(ALuint)*globalsize);
-    Sources = (ALuint*) Malloc(sizeof(ALuint)*globalsize);
+
+    Sources = (ALuint *)Malloc (sizeof(ALuint) * sources_number);
+    alGenSources(sources_number, Sources);
     
     // set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation
     // Position, Velocity and Orientation of the listener
     ALfloat ListenerPos[] = {0.0, 0.0, 0.0};
     ALfloat ListenerVel[] = {0.0, 0.0, 0.0};
-    ALfloat ListenerOri[] = {0.0, 0.0, -1.0,  0.0, 1.0, 0.0};
-    
+    ALfloat ListenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0};
+
     alListenerf (AL_GAIN,        1.0f       );
     alListenerfv(AL_POSITION,    ListenerPos);
     alListenerfv(AL_VELOCITY,    ListenerVel);
     alListenerfv(AL_ORIENTATION, ListenerOri);
-    
+
     if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge Error) - Failed to set Listener properties");
+        fprintf(stderr,"(Bridge ERROR) - Failed to set Listener properties\n");
         return -3;
     }
-    isBridgeReady = AL_TRUE;
-    
-    alGetError();  // clear any AL errors beforehand
+
+    the_sounds = (al_sound_t *)Malloc (sizeof(al_sound_t) * cache_size);
+    for (i = 0; i < cache_size; i++) {
+        the_sounds[i].filename = NULL;
+        the_sounds[i].buffer = -1;
+        the_sounds[i].source_index = -1;
+        the_sounds[i].stats = 0;
+    }
+
+    alGetError();
     return AL_TRUE;
 }
 
+
+// Stop all sounds, deallocate all memory and close OpenAL context
 void openal_close (void) {
-    /*Stop all sounds, deallocate all memory and close OpenAL */
     ALCcontext *context;
     ALCdevice  *device;
+    int i;
     
-    if (isBridgeReady == AL_FALSE) {
-        fprintf(stderr,"(Bridge Warning) - OpenAL not initialized");
+    if (instances_number == 0) {
+        fprintf(stderr,"(Bridge Warning) - OpenAL not initialized\n");
+        return;
+    }
+
+    instances_number--;
+    if (instances_number > 0) {
         return;
     }
     
-    alSourceStopv	(globalsize, Sources);
-    alDeleteSources (globalsize, Sources);
-    alDeleteBuffers (globalsize, Buffers);
-    
+    //TODO: free other stuff also
+    for (i = 0; i < cache_size; i++)
+        alDeleteBuffers (1, &the_sounds[i].buffer);
+    free(the_sounds);
+
+    alSourceStopv	(sources_number, Sources);
+    alDeleteSources (sources_number, Sources);
+
     free(Sources);
-    free(Buffers);
-    
+
     context = alcGetCurrentContext();
     device  = alcGetContextsDevice(context);
-    
+
     alcMakeContextCurrent(NULL);
     alcDestroyContext(context);
     alcCloseDevice(device);
-    
-    isBridgeReady = AL_FALSE;
-    
-    fprintf(stderr,"(Bridge Info) - closed");
-    
-    return;
-}
-
-ALboolean openal_ready (void) {
-    return isBridgeReady;
-}
 
+    fprintf(stderr,"(Bridge Info) - closed\n");
 
-void helper_realloc (void) {
-    /*expands allocated memory when loading more sound files than expected*/
-    int oldsize = globalsize;
-    globalsize += increment;
-    
-    fprintf(stderr,"(Bridge Info) - Realloc in process from %d to %d\n", oldsize, globalsize);
-    
-    Buffers = (ALuint*) Realloc(Buffers, sizeof(ALuint)*globalsize);
-    Sources = (ALuint*) Realloc(Sources, sizeof(ALuint)*globalsize);
-    
     return;
 }
 
 
+ALboolean openal_ready (void) {
+    if (instances_number >= 1) 
+        return AL_TRUE;
+    else
+        return AL_FALSE;
+}
+
+
+// Open a file, load into memory and allocate the Source buffer for playing
 int openal_loadfile (const char *filename){
-    /*Open a file, load into memory and allocate the Source buffer for playing*/
-    ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; /*Position of the source sound*/
-    ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; /*Velocity of the source sound*/
-    ALenum format;
+    ALenum format, error;
     ALsizei bitsize, freq;
+    uint32_t fileformat;
+    al_sound_t soundData;
+    int len, i;
     char *data;
-    uint32_t fileformat;
-    ALenum error;
     FILE *fp;
     
-    if (isBridgeReady == AL_FALSE) {
-        fprintf(stderr,"(Bridge Warning) - not initialized");
+    if (openal_ready() == AL_FALSE) {
+        fprintf(stderr,"(Bridge Warning) - not initialized\n");
         return -1;
     }
     
-    /*when the buffers are all used, we can expand memory to accept new files*/
-    if (globalindex == globalsize)
-        helper_realloc();
-    
-    /*detect the file format, as written in the first 4 bytes of the header*/
-    fp = Fopen (filename, "rb");
+    // if this sound is already loaded return the index from the_sounds
+    len = strlen(filename);
+    for (i = 0; i < cache_size; i++) {
+        if (the_sounds[i].filename != NULL && strncmp(the_sounds[i].filename, filename, len) == 0) {
+#ifdef DEBUG
+            fprintf(stderr,"(Bridge Debug) - sound %d is already loaded\n", i);
+#endif
+            return i;
+        }
+    }
+
+    if (cache_pointer >= cache_size) {
+        fprintf(stderr,"(Bridge ERROR) - Cache size limit reached; consider allocating more space\n", filename);
+        return -2;
+    }
     
-    if (fp == NULL)
-        return -2;
-    
-    error = fread (&fileformat, sizeof(uint32_t), 1, fp);
-    fclose (fp);
-    
-    if (error < 0) {
-        fprintf(stderr,"(Bridge Error) - File %s is too short", filename);
+    // detect the file format, as written in the first 4 bytes of the header
+    fp = Fopen (filename, "rb");
+
+    if (fp == NULL) {
+        fprintf(stderr,"(Bridge ERROR) - File %s not loaded\n", filename);
         return -3;
     }
-    
-    /*prepare the buffer to receive data*/
-    alGenBuffers(1, &Buffers[globalindex]);
-    
-    if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge Error) - Failed to allocate memory for buffers");
+
+    error = fread (&fileformat, sizeof(uint32_t), 1, fp);
+    fclose (fp);
+
+    if (error < 0) {
+        fprintf(stderr,"(Bridge ERROR) - File %s is too short\n", filename);
         return -4;
     }
-    
-    /*prepare the source to emit sound*/
-    alGenSources(1, &Sources[globalindex]);
-    
-    if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge Error) - Failed to allocate memory for sources");
-        return -5;
-    }
-    
+
     switch (ENDIAN_BIG_32(fileformat)) {
         case OGG_FILE_FORMAT:
             error = load_oggvorbis (filename, &format, &data, &bitsize, &freq);
@@ -211,156 +224,42 @@
             error = load_wavpcm (filename, &format, &data, &bitsize, &freq);
             break;
         default:
-            fprintf(stderr,"(Bridge Error) - File format (%08X) not supported", ENDIAN_BIG_32(fileformat));
-            return -6;
+            fprintf(stderr,"(Bridge ERROR) - File format (%08X) not supported\n", ENDIAN_BIG_32(fileformat));
+            return -5;
             break;
     }
+
+    if (error != 0) {
+        fprintf(stderr,"(Bridge ERROR) - error loading file %s\n", filename);
+        free(data);
+        return -6;
+    }
+
+    alGenBuffers(1, &soundData.buffer);
+    soundData.filename = filename;
+    soundData.source_index = -1;
+    soundData.stats = 0;
+    
+    if (AL_NO_ERROR != alGetError()) {
+        fprintf(stderr,"(Bridge ERROR) - Failed to allocate memory for buffers\n");
+        return -5;
+    }
     
-    if (error != 0) {
-        fprintf(stderr,"(Bridge Error) - error loading file %s", filename);
-        free(data);
-        return -7;
-    }
-    
-    //copy pcm data in one buffer and free it
-    alBufferData(Buffers[globalindex], format, data, bitsize, freq);
+    // copy pcm data in one buffer and free it
+    alBufferData(soundData.buffer, format, data, bitsize, freq);
     free(data);
-    
+
     if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge Error) - Failed to write data to buffers");
+        fprintf(stderr,"(Bridge ERROR) - Failed to write data to buffers\n");
         return -8;
     }
     
-    /*set source properties that it will use when it's in playback*/
-    alSourcei (Sources[globalindex], AL_BUFFER,   Buffers[globalindex]  );
-    alSourcef (Sources[globalindex], AL_PITCH,    1.0f                  );
-    alSourcef (Sources[globalindex], AL_GAIN,     1.0f                  );
-    alSourcefv(Sources[globalindex], AL_POSITION, SourcePos             );
-    alSourcefv(Sources[globalindex], AL_VELOCITY, SourceVel             );
-    alSourcei (Sources[globalindex], AL_LOOPING,  0                     );
-    
-    if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge Error) - Failed to set Source properties");
-        return -9;
-    }
-    
-    alGetError();  /* clear any AL errors beforehand */
-    
-    /*returns the index of the source you just loaded, increments it and exits*/
-    return globalindex++;
-}
-
-
-void openal_playsound (uint32_t index) {
-    openal_playsound_loop (index, 0);
-}
-
+    // clear any AL errors beforehand
+    alGetError();
 
-void openal_pausesound (uint32_t index) {
-    if (isBridgeReady == AL_TRUE && index < globalsize)
-        alSourcePause(Sources[index]);
-}
-
-
-void openal_stopsound (uint32_t index) {
-    openal_stopsound_free(index, 0);
-}
-
-
-void openal_freesound (uint32_t index){
-    if (isBridgeReady == AL_TRUE && index < globalsize)
-        alSourceStop(Sources[index]);
-    // STUB
-}
-
-
-void openal_playsound_loop (unsigned int index, char loops) {
-    if (isBridgeReady == AL_TRUE && index < globalsize) {
-        alSourcePlay(Sources[index]);
-        if (loops != 0)
-            openal_toggleloop(index);
-    }
-}
-
-void openal_stopsound_free (unsigned int index, char freesource) {
-    if (isBridgeReady == AL_TRUE && index < globalsize) {
-        alSourceStop(Sources[index]);
-        if (freesource != 0)
-            openal_freesound(index);
-    }
-}
+    fprintf(stderr,"(Bridge Info) - successfully loaded %s\n", filename);
 
-void openal_toggleloop (uint32_t index) {
-    ALint loop;
-    
-    if (isBridgeReady == AL_TRUE && index < globalsize) {
-        alGetSourcei (Sources[index], AL_LOOPING, &loop);
-        alSourcei (Sources[index], AL_LOOPING, !((uint8_t) loop) & 0x00000001);
-    }
-    
-}
-
-
-void openal_setvolume (uint32_t index, float gain) {
-    if (isBridgeReady == AL_TRUE && index < globalsize)
-        alSourcef (Sources[index], AL_GAIN, gain);
-}
-
-
-void openal_setglobalvolume (float gain) {
-    if (isBridgeReady == AL_TRUE)
-        alListenerf (AL_GAIN, gain);
-}
-
-void openal_togglemute () {
-    ALfloat gain;
-    
-    if (isBridgeReady == AL_TRUE) {
-        alGetListenerf (AL_GAIN, &gain);
-        if (gain > 0) {
-            old_gain = gain;
-            gain = 0;
-        } else
-            gain = old_gain;
-        
-        alListenerf (AL_GAIN, gain);
-    }
+    // returns the index of the source you just loaded, increments it and exits
+    the_sounds[cache_pointer] = soundData;
+    return cache_pointer++;
 }
-
-// Fade in or out by calling a helper thread
-void openal_fade (uint32_t index, uint16_t quantity, al_fade_t direction) {
-#ifndef _WIN32
-    pthread_t thread;
-#else
-    HANDLE Thread;
-#endif
-    fade_t *fade;
-    
-    if (isBridgeReady == AL_TRUE && index < globalsize) {
-        fade = (fade_t*) Malloc(sizeof(fade_t));
-        fade->index = index;
-        fade->quantity = quantity;
-        fade->type = direction;
-        
-#ifndef _WIN32
-        pthread_create(&thread, NULL, (void *)helper_fade, (void *)fade);
-        pthread_detach(thread);
-#else
-        Thread = (HANDLE) _beginthread((void *)helper_fade, 0, (void *)fade);
-#endif
-    }
-}
-
-void openal_fadein (uint32_t index, uint16_t quantity) {
-    openal_fade(index, quantity, AL_FADE_IN);
-}
-
-void openal_fadeout (uint32_t index, uint16_t quantity) {
-    openal_fade(index, quantity, AL_FADE_OUT);
-}
-
-
-void openal_setposition (uint32_t index, float x, float y, float z) {
-    if (isBridgeReady == AL_TRUE && index < globalsize)
-        alSource3f(Sources[index], AL_POSITION, x, y, z);;
-}
--- a/misc/openalbridge/openalbridge.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/openalbridge.h	Thu Jun 17 19:57:51 2010 +0200
@@ -20,6 +20,7 @@
 #define _OALB_INTERFACE_H
 
 #include "openalbridge_t.h"
+#include "commands.h"
 
 #ifdef __CPLUSPLUS
 extern "C" {
@@ -37,38 +38,9 @@
     // load an audio file into memory and map it to abuffer
     int  openal_loadfile          (const char *filename);
 
-    // play, pause, stop a single sound source
-    void openal_playsound         (unsigned int index);
-    void openal_pausesound        (unsigned int index);
-    void openal_stopsound         (unsigned int index);
 
-    // play a sound and set whether it should loop or not (0/1)
-    void openal_playsound_loop    (unsigned int index, char loops);
-
-    // stop a sound and free the associated buffer
-    void openal_stopsound_free    (unsigned int index, char freesource);
-
-    void openal_freesound         (unsigned int index);
-
-    // set or unset the looping property for a sound source
-    void openal_toggleloop        (unsigned int index);
-
-    // set position and volume of a sound source
-    void openal_setposition       (unsigned int index, float x, float y, float z);
-    void openal_setvolume         (unsigned int index, float gain);
-
-    // set volume for all sounds (gain interval is [0-1])
-    void openal_setglobalvolume   (float gain);
-
-    // mute or unmute all sounds
-    void openal_togglemute        (void);
-
-    // fade effect,
-    void openal_fade              (unsigned int index, unsigned short int quantity, al_fade_t direction);
-    void openal_fadein            (unsigned int index, unsigned short int quantity);
-    void openal_fadeout           (unsigned int index, unsigned short int quantity);
-
-
+    /******* other functions continue in commands.h *******/
+    
 #ifdef __CPLUSPLUS
 }
 #endif
--- a/misc/openalbridge/openalbridge_t.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/openalbridge_t.h	Thu Jun 17 19:57:51 2010 +0200
@@ -1,61 +1,74 @@
-/*
- * OpenAL Bridge - a simple portable library for OpenAL interface
- * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <stdint.h>
-
-#ifndef _OALB_INTERFACE_TYPES_H
-#define _OALB_INTERFACE_TYPES_H
-
-enum al_fade_enum {AL_FADE_IN, AL_FADE_OUT};
-typedef enum al_fade_enum al_fade_t;
-
-//data type for passing data between threads
-#pragma pack(1)
-typedef struct _fade_t {
-    uint32_t index;
-    uint16_t quantity;
-    al_fade_t type;
-} fade_t;
-#pragma pack()
-
-
-//data type for WAV header
-#pragma pack(1)
-typedef struct _WAV_header_t {
-    uint32_t ChunkID;
-    uint32_t ChunkSize;
-    uint32_t Format;
-    uint32_t Subchunk1ID;
-    uint32_t Subchunk1Size;
-    uint16_t AudioFormat;
-    uint16_t NumChannels;
-    uint32_t SampleRate;
-    uint32_t ByteRate;
-    uint16_t BlockAlign;
-    uint16_t BitsPerSample;
-    uint32_t Subchunk2ID;
-    uint32_t Subchunk2Size;
-} WAV_header_t;
-#pragma pack()
-
-
-#ifdef __CPLUSPLUS
-}
-#endif
-
-#endif /*_OALB_INTERFACE_TYPES_H*/
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdint.h>
+#include "al.h"
+
+#ifndef _OALB_INTERFACE_TYPES_H
+#define _OALB_INTERFACE_TYPES_H
+
+enum al_fade_enum {AL_FADE_IN, AL_FADE_OUT};
+typedef enum al_fade_enum al_fade_t;
+
+
+// data type to handle which source source is playing what
+#pragma pack(1)
+typedef struct _al_sound_t {
+    const char *filename;       // name of the sound file
+    ALuint buffer;              // actual sound content
+    uint32_t source_index;      // index of the associated source
+    uint32_t stats;             // number of times the sound has been played
+} al_sound_t;
+#pragma pack()
+
+
+// data type for passing data between threads
+#pragma pack(1)
+typedef struct _fade_t {
+    uint32_t index;
+    uint16_t quantity;
+    al_fade_t type;
+} fade_t;
+#pragma pack()
+
+
+// data type for WAV header
+#pragma pack(1)
+typedef struct _WAV_header_t {
+    uint32_t ChunkID;
+    uint32_t ChunkSize;
+    uint32_t Format;
+    uint32_t Subchunk1ID;
+    uint32_t Subchunk1Size;
+    uint16_t AudioFormat;
+    uint16_t NumChannels;
+    uint32_t SampleRate;
+    uint32_t ByteRate;
+    uint16_t BlockAlign;
+    uint16_t BitsPerSample;
+    uint32_t Subchunk2ID;
+    uint32_t Subchunk2Size;
+} WAV_header_t;
+#pragma pack()
+
+
+#ifdef __CPLUSPLUS
+}
+#endif
+
+#endif /*_OALB_INTERFACE_TYPES_H*/
--- a/misc/openalbridge/wrappers.c	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/wrappers.c	Thu Jun 17 19:57:51 2010 +0200
@@ -19,16 +19,15 @@
 #include "wrappers.h"
 #include "openalbridge_t.h"
 
-extern ALint *Sources;
 
 void *Malloc (size_t nbytes) {
     void *aptr;
 
     if ((aptr = malloc(nbytes)) == NULL) {
-        fprintf(stderr,"(Bridge Fatal Error) - not enough memory");
+        fprintf(stderr,"(Bridge FATAL) - not enough memory\n");
         abort();
     }
-    
+
     return aptr;
 }
 
@@ -37,7 +36,7 @@
     aptr = realloc(aptr, nbytes);
 
     if (aptr == NULL) {
-        fprintf(stderr,"(Bridge Fatal Error) - not enough memory");
+        fprintf(stderr,"(Bridge FATAL) - not enough memory\n");
         abort();
     }
 
@@ -50,71 +49,9 @@
 
     fp = fopen(fname,mode);
     if (fp == NULL)
-        fprintf(stderr,"(Bridge Error) - can't open file %s in mode '%s'", fname, mode);
+        fprintf(stderr,"(Bridge Error) - can't open file %s in mode '%s'\n", fname, mode);
 
     return fp;
 }
 
 
-void helper_fade(void *tmp) {
-    ALfloat gain;
-    ALfloat target_gain;
-    fade_t *fade;
-    uint32_t index;
-    uint16_t quantity;
-    al_fade_t type;
-
-    fade = tmp;
-    index = fade->index;
-    quantity = fade->quantity;
-    type = fade->type;
-    free (fade);
-
-    if (type == AL_FADE_IN) {
-#ifdef DEBUG
-        fprintf(stderr,"(Bridge Info) - Fade-in in progress [index %d quantity %d]", index, quantity);
-#endif
-
-        // save the volume desired after the fade
-        alGetSourcef(Sources[index], AL_GAIN, &target_gain);
-        if (target_gain > 1.0f || target_gain <= 0.0f)
-            target_gain = 1.0f;
-
-        alSourcePlay(Sources[index]);
-
-        for (gain = 0.0f ; gain <= target_gain; gain += (float) quantity/10000) {
-#ifdef TRACE
-            err_msg("(%s) DEBUG - Fade-in set gain to %f", gain);
-#endif
-            alSourcef(Sources[index], AL_GAIN, gain);
-            usleep(10000);
-        }
-    } else {
-        alGetSourcef(Sources[index], AL_GAIN, &target_gain);
-
-        for (gain = target_gain; gain >= 0.00f; gain -= (float) quantity/10000) {
-#ifdef TRACE
-            err_msg("(%s) DEBUG - Fade-out set gain to %f", gain);
-#endif
-            alSourcef(Sources[index], AL_GAIN, gain);
-            usleep(10000);
-        }
-
-        if (AL_NO_ERROR != alGetError())
-            fprintf(stderr,"(Bridge Warning) - Failed to set fade-out effect");
-
-        // stop that sound and reset its volume
-        alSourceStop (Sources[index]);
-        alSourcef (Sources[index], AL_GAIN, target_gain);
-    }
-
-    if (AL_NO_ERROR != alGetError())
-        fprintf(stderr,"(Bridge Warning) - Failed to set fade effect");
-
-#ifndef _WIN32
-    pthread_exit(NULL);
-#else
-    _endthread();
-#endif
-}
-
--- a/misc/openalbridge/wrappers.h	Thu Jun 17 11:42:23 2010 -0400
+++ b/misc/openalbridge/wrappers.h	Thu Jun 17 19:57:51 2010 +0200
@@ -20,6 +20,7 @@
 #define _OALB_WRAPPERS_H
 
 #include "globals.h"
+#include "openalbridge_t.h"
 
 void *Malloc (size_t nbytes);
 void *Realloc (void *aptr, size_t nbytes);
--- a/project_files/HedgewarsMobile/Hedgewars_Prefix.pch	Thu Jun 17 11:42:23 2010 -0400
+++ b/project_files/HedgewarsMobile/Hedgewars_Prefix.pch	Thu Jun 17 19:57:51 2010 +0200
@@ -21,3 +21,12 @@
 #endif
  
 #define ZAssert(condition, ...) do { if (!(condition)) { ALog(__VA_ARGS__); }} while(0)
+
+#if !__IPHONE_3_2
+typedef enum {
+    UIUserInterfaceIdiomPhone,           // iPhone and iPod touch style UI
+    UIUserInterfaceIdiomPad,             // iPad style UI
+} UIUserInterfaceIdiom;
+#define UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPhone
+#define UIPopoverController id
+#endif // ifndef __IPHONE_3_2