diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7b443d5..0864578 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,5 +14,5 @@ foreach(quest_name ${quests})
 endforeach(quest_name ${quests})
 
 # tests
-add_subdirectory(tests)
+#add_subdirectory(tests)
 
diff --git a/include/entities/Boomerang.h b/include/entities/Boomerang.h
index 852aa4a..03fe2f6 100644
--- a/include/entities/Boomerang.h
+++ b/include/entities/Boomerang.h
@@ -41,7 +41,7 @@ class Boomerang: public MapEntity {
 
   public:
 
-    Boomerang(Hero &hero, double boomerang_angle);
+    Boomerang(Hero &hero, float boomerang_angle);
     ~Boomerang();
 
     EntityType get_type();
diff --git a/include/entities/MapEntity.h b/include/entities/MapEntity.h
index 1ec4ce3..07ee50e 100644
--- a/include/entities/MapEntity.h
+++ b/include/entities/MapEntity.h
@@ -266,7 +266,7 @@ class MapEntity {
     bool is_facing_point_in(const Rectangle &rectangle, int direction);
     bool is_center_in(const Rectangle &rectangle);
 
-    double get_vector_angle(MapEntity &other);
+    float get_vector_angle(MapEntity &other);
     int get_distance(MapEntity &other);
     int get_distance(int x, int y);
 
diff --git a/include/lowlevel/Geometry.h b/include/lowlevel/Geometry.h
index 2c045e5..f9f26be 100644
--- a/include/lowlevel/Geometry.h
+++ b/include/lowlevel/Geometry.h
@@ -27,18 +27,18 @@ class Geometry {
     // Mathematic constants:
     // we don't use the ones from cmath
     // because they are not ANSI
-    static const double PI;
-    static const double TWO_PI;
-    static const double PI_OVER_2;
-    static const double THREE_PI_OVER_2;
-    static const double SQRT_2;
+    static const float PI;
+    static const float TWO_PI;
+    static const float PI_OVER_2;
+    static const float THREE_PI_OVER_2;
+    static const float SQRT_2;
 
-    static const int radians_to_degrees(double radians);
-    static const double degrees_to_radians(double degrees);
+    static const int radians_to_degrees(float radians);
+    static const float degrees_to_radians(float degrees);
 
-    static double get_distance(int x1, int y1, int x2, int y2);
-    static double get_angle(int x1, int y1, int x2, int y2);
-    static const Rectangle get_xy(double angle, int distance);
-    static const Rectangle get_xy(const Rectangle &xy1, double angle, int distance);
+    static float get_distance(int x1, int y1, int x2, int y2);
+    static float get_angle(int x1, int y1, int x2, int y2);
+    static const Rectangle get_xy(float angle, int distance);
+    static const Rectangle get_xy(const Rectangle &xy1, float angle, int distance);
 };
 
diff --git a/include/lowlevel/Music.h b/include/lowlevel/Music.h
index 2ce9448..3569cec 100644
--- a/include/lowlevel/Music.h
+++ b/include/lowlevel/Music.h
@@ -20,7 +20,6 @@
 #include "Common.h"
 #include "lowlevel/Sound.h"
 #include <map>
-#include <AL/al.h>
 
 /**
  * @brief Represents a music that can be played.
@@ -39,33 +38,25 @@ class Music { // TODO make a subclass for each format, or at least make a better
     /**
      * The music file formats recognized.
      */
-    enum Format {
-      SPC,	/**< original Snes music */
-      IT,	/**< Impulse Tracker module */
-      OGG       /**< Ogg Vorbis */
-    };
-
+    //enum Format {
+    //  SPC,	/**< original Snes music */
+    //  IT,	/**< Impulse Tracker module */
+    //  OGG       /**< Ogg Vorbis */
+    //};
+    
+    Mix_Music* mus;
     MusicId id;							/**< id of this music */
     std::string file_name;					/**< name of the file to play */
-    Format format;						/**< format of the music, detected from the file name */
-
-    // OGG specific
-    OggVorbis_File ogg_file;					/**< the file used by the vorbisfile lib */
-    Sound::SoundFromMemory ogg_mem;				/**< the encoded music loaded in memory, passed to the vorbisfile lib as user data */
+    //Format format;						/**< format of the music, detected from the file name */
 
-    static const int nb_buffers = 8;
-    ALuint buffers[nb_buffers];					/**< multiple buffers used to stream the music */
-    ALuint source;						/**< the OpenAL source streaming the buffers */
+    static bool initialized;					/**< indicates that the audio system is initialized */
+//    static const int nb_buffers = 8;
 
-    static SpcDecoder *spc_decoder;				/**< the SPC decoder */
-    static ItDecoder *it_decoder;                               /**< the IT decoder */
     static float volume;					/**< volume of musics (0.0 to 1.0) */
 
     static Music *current_music;				/**< the music currently played (if any) */
     static std::map<MusicId,Music> all_musics;			/**< all musics created before */
 
-    void update_playing();
-
   public:
 
     static const MusicId none;					/**< special id indicating that there is no music */
@@ -91,10 +82,6 @@ class Music { // TODO make a subclass for each format, or at least make a better
     void stop();
     bool is_paused();
     void set_paused(bool pause);
-
-    void decode_spc(ALuint destination_buffer, ALsizei nb_samples);
-    void decode_it(ALuint destination_buffer, ALsizei nb_samples);
-    void decode_ogg(ALuint destination_buffer, ALsizei nb_samples);
 };
 
 #endif
diff --git a/include/lowlevel/Sound.h b/include/lowlevel/Sound.h
index 9c8cbee..5fc37bb 100644
--- a/include/lowlevel/Sound.h
+++ b/include/lowlevel/Sound.h
@@ -20,9 +20,7 @@
 #include "Common.h"
 #include <list>
 #include <map>
-#include <AL/al.h>
-#include <AL/alc.h>
-#include <vorbis/vorbisfile.h>
+#include <SDL/SDL_mixer.h>
 
 /**
  * @brief Represents a sound effect that can be played in the program.
@@ -34,46 +32,16 @@
  * This class and the Music class are the only ones that depend on the audio mixer library (OpenAL).
  */
 class Sound {
-
   private:
-
-    static ALCdevice* device;
-    static ALCcontext* context;
-
+    Mix_Chunk* snd;
     SoundId id;							/**< id of this sound */
-    ALuint buffer;						/**< the OpenAL buffer containing the PCM decoded data of this sound */
-    std::list<ALuint> sources;					/**< the sources currently playing this sound */
     static std::list<Sound*> current_sounds;			/**< the sounds currently playing */
     static std::map<SoundId,Sound> all_sounds;			/**< all sounds created before */
 
     static bool initialized;					/**< indicates that the audio system is initialized */
     static float volume;					/**< the volume of sound effects (0.0 to 1.0) */
-
-    ALuint decode_file(const std::string &file_name);
-    bool update_playing();
-
   public:
 
-    // libvorbisfile
-
-    /**
-     * @brief Buffer containing an encoded sound file.
-     */
-    struct SoundFromMemory {
-      char *data;               /**< the buffer */
-      size_t size;              /**< size of the buffer in bytes */
-      size_t position;          /**< current position in the buffer */
-    };
-
-    // functions to load the encoded sound from memory
-    static ov_callbacks ogg_callbacks;           /**< vorbisfile object used to load the encoded sound from memory */
-    static size_t cb_read(void* ptr, size_t size, size_t nmemb, void* datasource);
-
-    /*
-    static int cb_seek(void* datasource, ogg_int64_t offset, int whence);
-    static long cb_tell(void* datasource);
-*/
-
     Sound();
     Sound(const SoundId &sound_id);
     ~Sound();
diff --git a/include/movements/RectilinearMovement.h b/include/movements/RectilinearMovement.h
index 74855e4..95b9ce4 100644
--- a/include/movements/RectilinearMovement.h
+++ b/include/movements/RectilinearMovement.h
@@ -34,12 +34,12 @@ class RectilinearMovement: public Movement {
   private:
 
     // speed vector
-    double angle;                               /**< angle between the speed vector and the horizontal axis in radians */
-    double x_speed;				/**< X speed of the object to move in pixels per second.
+    float angle;                               /**< angle between the speed vector and the horizontal axis in radians */
+    float x_speed;				/**< X speed of the object to move in pixels per second.
 						 * 0: stopped
 						 * positive value: moving to the right
 						 * negative value: moving to the left */
-    double y_speed;				/**< Y speed of the object to move in pixels per second.
+    float y_speed;				/**< Y speed of the object to move in pixels per second.
 						 * 0: stopped
 						 * positive value: moving downwards
 						 * negative value: moving upwards */
@@ -85,14 +85,14 @@ class RectilinearMovement: public Movement {
     bool has_to_move_now();
 
     // speed vector
-    double get_x_speed();
-    double get_y_speed();
-    double get_speed();
-    void set_x_speed(double x_speed);
-    void set_y_speed(double y_speed);
-    void set_speed(double speed);
-    double get_angle();
-    void set_angle(double angle);
+    float get_x_speed();
+    float get_y_speed();
+    float get_speed();
+    void set_x_speed(float x_speed);
+    void set_y_speed(float y_speed);
+    void set_speed(float speed);
+    float get_angle();
+    void set_angle(float angle);
     int get_displayed_direction4();
 
     // movement
diff --git a/include/movements/TemporalMovement.h b/include/movements/TemporalMovement.h
index 49cda82..1ebdefa 100644
--- a/include/movements/TemporalMovement.h
+++ b/include/movements/TemporalMovement.h
@@ -45,7 +45,7 @@ class TemporalMovement: public SmoothMovement {
 
   public:
 
-    TemporalMovement(int speed, double angle, uint32_t duration, bool smooth = true);
+    TemporalMovement(int speed, float angle, uint32_t duration, bool smooth = true);
     TemporalMovement(int speed, const Rectangle &source_xy, const Rectangle &target_xy, uint32_t time, bool smooth = true);
     ~TemporalMovement();
 
@@ -53,7 +53,7 @@ class TemporalMovement: public SmoothMovement {
     void set_suspended(bool suspended);
     bool is_finished();
     void set_finished();
-    void start(int speed, double angle, uint32_t duration);
+    void start(int speed, float angle, uint32_t duration);
     void set_duration(uint32_t duration);
 
     // properties
diff --git a/include/snes_spc/blargg_source.h b/include/snes_spc/blargg_source.h
index 5e45c4f..b6703e0 100644
--- a/include/snes_spc/blargg_source.h
+++ b/include/snes_spc/blargg_source.h
@@ -55,8 +55,8 @@ DEF_MIN_MAX( int )
 DEF_MIN_MAX( unsigned )
 DEF_MIN_MAX( long )
 DEF_MIN_MAX( unsigned long )
-DEF_MIN_MAX( float )
-DEF_MIN_MAX( double )
+//DEF_MIN_MAX( float )
+//DEF_MIN_MAX( float )
 
 #undef DEF_MIN_MAX
 
diff --git a/quests/zsxd/data/zsxd b/quests/zsxd/data/zsxd
index f417b00..c01ca79 100644
--- a/quests/zsxd/data/zsxd
+++ b/quests/zsxd/data/zsxd
@@ -1,2 +1,2 @@
 #!/bin/bash
-/usr/local/bin/solarus -datapath=/usr/local/share/solarus/zsxd 
+/home/users/seb/Projects/Caanoo/target/Mystery_of_Solarus_XD/bin/solarus -datapath=/home/users/seb/Projects/Caanoo/target/Mystery_of_Solarus_XD/share/solarus/zsxd 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 23e7f80..15b61bd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -7,9 +7,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/")
 find_package(SDL)
 find_package(SDL_image)
 find_package(SDL_ttf)
-find_package(OpenAL)
-find_package(VorbisFile)
-find_package(ModPlug)
+find_package(SDL_mixer)
+#find_package(OpenAL)
+#find_package(VorbisFile)
+#find_package(ModPlug)
 find_package(Lua51)
 find_package(PhysFS)
 
@@ -49,6 +50,7 @@ target_link_libraries(solarus
   ${SDL_LIBRARY}
   ${SDLIMAGE_LIBRARY}
   ${SDLTTF_LIBRARY}
+  ${SDLMIXER_LIBRARY}
   ${OPENAL_LIBRARY}
   ${LUA_LIBRARY}
   ${PHYSFS_LIBRARY}
diff --git a/src/GameoverSequence.cpp b/src/GameoverSequence.cpp
index 39c6135..5ba62e1 100644
--- a/src/GameoverSequence.cpp
+++ b/src/GameoverSequence.cpp
@@ -126,7 +126,7 @@ void GameoverSequence::update() {
       }
       else {
 	state = MENU;
-	Music::play("game_over.spc");
+	Music::play("game_over.IT");
 	fairy_x = 76;
 	fairy_y = 124;
 	cursor_position = 0;
diff --git a/src/Solarus.cpp b/src/Solarus.cpp
index 0123aa0..73ccae8 100755
--- a/src/Solarus.cpp
+++ b/src/Solarus.cpp
@@ -26,6 +26,12 @@
 #include "StringResource.h"
 #include "DebugKeys.h"
 
+#include <iostream>
+
+//#define PERF_DEBUG
+//#define PERF_DEBUG_2
+//#define PERF_DEBUG_3
+
 /**
  * @brief Initializes the game engine.
  *
@@ -46,6 +52,7 @@ Solarus::Solarus(int argc, char **argv) {
 
   // create the first screen
   current_screen = new LanguageScreen(*this);
+  //current_screen = new SelectionMenu(*this);
   exiting = false;
 }
 
@@ -117,23 +124,37 @@ void Solarus::main_loop() {
   // main loop
   InputEvent *event;
   uint32_t now;
+#ifdef PERF_DEBUG
+  uint32_t a, b, c, d;
+#endif
   uint32_t next_frame_date = System::now();
   uint32_t frame_interval = 25; // time interval between to displays
   int delay;
   bool just_displayed = false; // to detect when the FPS number needs to be decreased
 
   while (!is_exiting()) {
+#ifdef PERF_DEBUG
+    a=SDL_GetTicks();
+#endif
 
     // handle the input events
-    event = InputEvent::get_event();
-    if (event != NULL) {
-      notify_event(*event);
-      delete event;
-    }
+    do {
+      event = InputEvent::get_event();
+      if (event != NULL) {
+        notify_event(*event);
+        delete event;
+      }
+    } while (event != NULL);
 
+#ifdef PERF_DEBUG
+    b=SDL_GetTicks();
+#endif
     // update the current screen
     update();
 
+#ifdef PERF_DEBUG
+    c=SDL_GetTicks();
+#endif
     // go to another screen?
     if (current_screen->is_screen_finished()) {
       Screen *next_screen = current_screen->get_next_screen();
@@ -157,7 +178,7 @@ void Solarus::main_loop() {
 	// see if the FPS number is too high
 	if (just_displayed && frame_interval <= 30) {
 	  frame_interval += 5; // display the screen less often
-	  //std::cout << "\rFPS: " << (1000 / frame_interval) << std::flush;
+	  //std::cout << "+FPS: " << (1000 / frame_interval) <<std::endl;
 	}
 
 	next_frame_date = now + frame_interval;
@@ -173,10 +194,14 @@ void Solarus::main_loop() {
 	if (delay >= 15) {
 	  // if we have much time, increase the FPS number
 	  frame_interval--;
-	  //std::cout << "\rFPS: " << (1000 / frame_interval) << std::flush;
+	  //std::cout << "FPS: " << (1000 / frame_interval) << std::endl;
 	}
       }
     }
+#ifdef PERF_DEBUG
+  d=SDL_GetTicks();
+  std::cout << "Total: " << d-a << " | 1-> " << b-a << " | 2-> " << c-b << " | 3-> " << d-c << " | display: " << just_displayed << std::endl;
+#endif
   }
 }
 
@@ -214,6 +239,11 @@ void Solarus::notify_event(InputEvent &event) {
     // a key is released
     debug_keys->key_released(key);
   }
+#ifdef CAANOO
+  else if (event.is_joypad_button_released() && event.get_joypad_button() == 6) {
+    exiting = true;
+  }
+#endif
 
   // send the event to the current screen
   current_screen->notify_event(event);
@@ -225,10 +255,25 @@ void Solarus::notify_event(InputEvent &event) {
  * This function is called repeatedly by the main loop.
  */
 void Solarus::update() {
+#ifdef PERF_DEBUG_2
+  uint32_t a,b,c,d;
 
+  a = SDL_GetTicks();
+#endif
   debug_keys->update();
+#ifdef PERF_DEBUG_2
+  b = SDL_GetTicks();
+#endif
+  //that's the slow part
   current_screen->update();
+#ifdef PERF_DEBUG_2
+  c = SDL_GetTicks();
+#endif
   System::update();
+#ifdef PERF_DEBUG_2
+  d = SDL_GetTicks();
+    std::cout << " [2] - | a: " << b-a << " | b: " << c-b << " | c: " << d-c << std::endl;
+#endif
 }
 
 /**
@@ -238,8 +283,19 @@ void Solarus::update() {
  */
 void Solarus::display() {
 
-  root_surface->fill_with_color(Color::get_black());
+//  root_surface->fill_with_color(Color::get_black());
+#ifdef PERF_DEBUG_3
+  uint32_t a,b,c;
+  a = SDL_GetTicks();
+#endif
   current_screen->display(root_surface);
+#ifdef PERF_DEBUG_3
+  b = SDL_GetTicks();
+#endif
   VideoManager::get_instance()->display(root_surface);
+#ifdef PERF_DEBUG_3
+  c = SDL_GetTicks();
+    std::cout << " [3] - | a: " << b-a << " | b: " << c-b << std::endl;
+#endif
 }
 
diff --git a/src/entities/Boomerang.cpp b/src/entities/Boomerang.cpp
index f7fe745..932a062 100644
--- a/src/entities/Boomerang.cpp
+++ b/src/entities/Boomerang.cpp
@@ -33,7 +33,7 @@
  * @param hero the hero
  * @param boomerang_angle the angle of the boomerang trajectory in radians
  */
-Boomerang::Boomerang(Hero &hero, double boomerang_angle):
+Boomerang::Boomerang(Hero &hero, float boomerang_angle):
   MapEntity(), hero(hero), has_to_go_back(false), going_back(false) {
 
   // initialize the entity
diff --git a/src/entities/Enemy.cpp b/src/entities/Enemy.cpp
index 223c6a2..0771650 100644
--- a/src/entities/Enemy.cpp
+++ b/src/entities/Enemy.cpp
@@ -725,7 +725,7 @@ void Enemy::attack_hero(Hero &hero, Sprite *this_sprite) {
     if (minimum_shield_needed != 0 &&
 	get_equipment().has_ability("shield", minimum_shield_needed)) {
 
-      double angle = hero.get_vector_angle(*this);
+      float angle = hero.get_vector_angle(*this);
       int protected_direction = (int) ((angle + Geometry::PI_OVER_2 / 2.0) * 4 / Geometry::TWO_PI);
       protected_direction = (protected_direction + 4) % 4;
 
@@ -896,7 +896,7 @@ void Enemy::hurt(MapEntity &source) {
 
   // push the enemy back
   if (pushed_back_when_hurt) {
-    double angle = source.get_vector_angle(*this);
+    float angle = source.get_vector_angle(*this);
     set_movement(new TemporalMovement(120, angle, 200));
   }
   else {
diff --git a/src/entities/Hero.cpp b/src/entities/Hero.cpp
index 41071c4..5673174 100755
--- a/src/entities/Hero.cpp
+++ b/src/entities/Hero.cpp
@@ -274,7 +274,7 @@ void Hero::update_ground() {
     if (is_ground_visible() && get_movement() != NULL) {
 
       // a special ground is displayed under the hero and it's time to play a sound
-      double speed = ((RectilinearMovement*) get_movement())->get_speed();
+      float speed = ((RectilinearMovement*) get_movement())->get_speed();
       next_ground_date = now + std::max(150, (int) (20000 / speed));
       if (sprites->is_walking() && state->is_touching_ground()) {
         sprites->play_ground_sound();
diff --git a/src/entities/MapEntity.cpp b/src/entities/MapEntity.cpp
index c5541a8..b849deb 100644
--- a/src/entities/MapEntity.cpp
+++ b/src/entities/MapEntity.cpp
@@ -1493,7 +1493,7 @@ bool MapEntity::is_center_in(const Rectangle &rectangle) {
  * @param other the other entity
  * @return the angle of the vector in radians
  */
-double MapEntity::get_vector_angle(MapEntity &other) {
+float MapEntity::get_vector_angle(MapEntity &other) {
   return Geometry::get_angle(get_x(), get_y(), other.get_x(), other.get_y());
 }
 
diff --git a/src/hero/BoomerangState.cpp b/src/hero/BoomerangState.cpp
index 34f1139..069c63d 100644
--- a/src/hero/BoomerangState.cpp
+++ b/src/hero/BoomerangState.cpp
@@ -77,7 +77,7 @@ void Hero::BoomerangState::update() {
     else {
       boomerang_direction8 = direction_pressed8;
     }
-    double angle = Geometry::degrees_to_radians(boomerang_direction8 * 45);
+    float angle = Geometry::degrees_to_radians(boomerang_direction8 * 45);
     get_entities().add_entity(new Boomerang(hero, angle));
 
     hero.set_state(new FreeState(hero));
diff --git a/src/hero/HurtState.cpp b/src/hero/HurtState.cpp
index d3043e3..4f0612f 100644
--- a/src/hero/HurtState.cpp
+++ b/src/hero/HurtState.cpp
@@ -73,7 +73,7 @@ void Hero::HurtState::start(State *previous_state) {
   get_sprites().set_animation_hurt();
   get_sprites().blink();
 
-  double angle = Geometry::get_angle(source_xy.get_x(), source_xy.get_y(),
+  float angle = Geometry::get_angle(source_xy.get_x(), source_xy.get_y(),
       hero.get_x(), hero.get_y());
   hero.set_movement(new TemporalMovement(120, angle, 200));
 }
diff --git a/src/hero/RunningState.cpp b/src/hero/RunningState.cpp
index 1cb0b43..4d18281 100644
--- a/src/hero/RunningState.cpp
+++ b/src/hero/RunningState.cpp
@@ -94,7 +94,7 @@ void Hero::RunningState::update() {
   if (phase == 0) {
     
     if (now >= next_phase_date) {
-      double angle = Geometry::degrees_to_radians(get_sprites().get_animation_direction() * 90);
+      float angle = Geometry::degrees_to_radians(get_sprites().get_animation_direction() * 90);
       hero.clear_movement();
       hero.set_movement(new TemporalMovement(300, angle , 10000));
       get_sprites().set_animation_running();
diff --git a/src/lowlevel/Geometry.cpp b/src/lowlevel/Geometry.cpp
index 017540a..49d9d69 100644
--- a/src/lowlevel/Geometry.cpp
+++ b/src/lowlevel/Geometry.cpp
@@ -21,34 +21,34 @@
 /**
  * @brief The pi constant.
  */
-const double Geometry::PI = 3.14159265358979323846;
+const float Geometry::PI = 3.14159265358979323846;
 
 /**
  * @brief 2 * pi.
  */
-const double Geometry::TWO_PI = 2.0 * PI;
+const float Geometry::TWO_PI = 2.0 * PI;
 
 /**
  * @brief pi / 2.
  */
-const double Geometry::PI_OVER_2 = PI / 2.0;
+const float Geometry::PI_OVER_2 = PI / 2.0;
 
 /**
  * @brief 3 * pi / 2.
  */
-const double Geometry::THREE_PI_OVER_2 = 3 * PI_OVER_2;
+const float Geometry::THREE_PI_OVER_2 = 3 * PI_OVER_2;
 
 /**
  * @brief Square root of 2.
  */
-const double Geometry::SQRT_2 = 1.41421356237309504880;
+const float Geometry::SQRT_2 = 1.41421356237309504880;
 
 /**
  * @brief Converts an angle in radians into an angle in degrees.
  * @param radians angle in radians
  * @return the degrees value
  */
-const int Geometry::radians_to_degrees(double radians) {
+const int Geometry::radians_to_degrees(float radians) {
   return (int) (radians * 360.0 / TWO_PI);
 }
 
@@ -57,7 +57,7 @@ const int Geometry::radians_to_degrees(double radians) {
  * @param degrees angle in degrees
  * @return the radians value
  */
-const double Geometry::degrees_to_radians(double degrees) {
+const float Geometry::degrees_to_radians(float degrees) {
   return degrees * TWO_PI / 360.0;
 }
 
@@ -69,7 +69,7 @@ const double Geometry::degrees_to_radians(double degrees) {
  * @param y2 y coordinate of the second point
  * @return the distance in pixels
  */
-double Geometry::get_distance(int x1, int y1, int x2, int y2) {
+float Geometry::get_distance(int x1, int y1, int x2, int y2) {
 
   int dx = x2 - x1;
   int dy = y2 - y1;
@@ -84,14 +84,14 @@ double Geometry::get_distance(int x1, int y1, int x2, int y2) {
  * @param y2 y coordinate of the second point
  * @return the angle in radians
  */
-double Geometry::get_angle(int x1, int y1, int x2, int y2) {
+float Geometry::get_angle(int x1, int y1, int x2, int y2) {
 
   int dx = x2 - x1;
   int dy = y2 - y1;
 
-  double angle;
+  float angle;
   if (dx != 0) {
-    angle = std::atan((double) -dy / (double) dx);
+    angle = std::atan((float) -dy / (float) dx);
 
     if (dx < 0) {
       angle += PI;
@@ -111,7 +111,7 @@ double Geometry::get_angle(int x1, int y1, int x2, int y2) {
  * @param distance length of the vector in pixels
  * @return the coordinates of the second point
  */
-const Rectangle Geometry::get_xy(double angle, int distance) {
+const Rectangle Geometry::get_xy(float angle, int distance) {
 
   return Rectangle((int) (distance * std::cos(angle)), (int) (-distance * std::sin(angle)));
 }
@@ -123,7 +123,7 @@ const Rectangle Geometry::get_xy(double angle, int distance) {
  * @param distance length of the vector in pixels
  * @return the coordinates of the second point
  */
-const Rectangle Geometry::get_xy(const Rectangle &xy1, double angle, int distance) {
+const Rectangle Geometry::get_xy(const Rectangle &xy1, float angle, int distance) {
 
   Rectangle xy = get_xy(angle, distance);
   xy.add_xy(xy1.get_x(), xy1.get_y());
diff --git a/src/lowlevel/Music.cpp b/src/lowlevel/Music.cpp
index c33c044..94dca08 100644
--- a/src/lowlevel/Music.cpp
+++ b/src/lowlevel/Music.cpp
@@ -20,23 +20,25 @@
 #include "lowlevel/FileTools.h"
 #include "lowlevel/Debug.h"
 #include "lowlevel/StringConcat.h"
+#include "lowlevel/physfsrwops.h"
 #include "Configuration.h"
 
-const int Music::nb_buffers;
-SpcDecoder *Music::spc_decoder = NULL;
-ItDecoder *Music::it_decoder = NULL;
 float Music::volume = 1.0;
 Music *Music::current_music = NULL;
 std::map<MusicId,Music> Music::all_musics;
 
 const MusicId Music::none = "none";
 const MusicId Music::unchanged = "same";
+bool Music::initialized = false;
+
+SDL_Thread *thread;
+
 
 /**
  * @brief Empty constructor.
  */
 Music::Music():
-  id(none) {
+  mus(NULL), id(none) {
 
 }
 
@@ -45,7 +47,7 @@ Music::Music():
  * @param music_id id of the music (a file name)
  */
 Music::Music(const MusicId &music_id):
-  id(music_id) {
+  mus(NULL), id(music_id) {
 
   if (!is_initialized()) {
     return;
@@ -58,25 +60,6 @@ Music::Music(const MusicId &music_id):
   size_t index = music_id.find_last_of(".");
   Debug::check_assertion(index != std::string::npos && index != music_id.size(),
     StringConcat() << "Invalid music file name: " << music_id);
-  std::string extension = music_id.substr(index + 1);
-
-  if (extension == "spc" || extension == "SPC" || extension == "Spc") {
-    format = SPC;
-  }
-  else if (extension == "it" || extension == "IT" || extension == "It") {
-    format = IT;
-  }
-  else if (extension == "ogg" || extension == "OGG" || extension == "Ogg") {
-    format = OGG;
-  }
-  else {
-    Debug::die(StringConcat() << "Unrecognized music file format: " << music_id);
-  }
-
-  for (int i = 0; i < nb_buffers; i++) {
-    buffers[i] = AL_NONE;
-  }
-  source = AL_NONE;
 }
 
 /**
@@ -91,19 +74,17 @@ Music::~Music() {
   if (current_music == this) {
     stop();
   }
+  if (mus != NULL)
+    Mix_FreeMusic(mus);
 }
 
 /**
  * @brief Initializes the music system.
  */
 void Music::initialize() {
-
-  // initialize the decoding features
-  spc_decoder = new SpcDecoder();
-  it_decoder = new ItDecoder();
-
   // get the music volume from the configuration file
   set_volume(Configuration::get_value("music_volume", 100));
+  initialized=true;
 }
 
 /**
@@ -111,8 +92,6 @@ void Music::initialize() {
  */
 void Music::quit() {
   if (is_initialized()) {
-    delete spc_decoder;
-    delete it_decoder;
     all_musics.clear();
   }
 }
@@ -122,7 +101,7 @@ void Music::quit() {
  * @return true if the music system is initilialized
  */
 bool Music::is_initialized() {
-  return spc_decoder != NULL;
+  return initialized;
 }
 
 /**
@@ -144,10 +123,15 @@ void Music::set_volume(int volume) {
 
   Configuration::set_value("music_volume", volume);
   Music::volume = volume / 100.0;
+  Mix_VolumeMusic(volume);
+    if (volume==0 && current_music != NULL) {
+      current_music->stop();
+      current_music = NULL;
+    }
 
-  if (current_music != NULL) {
+/*  if (current_music != NULL) {
     alSourcef(current_music->source, AL_GAIN, Music::volume);
-  }
+  }*/
 }
 
 /**
@@ -213,147 +197,12 @@ void Music::play(const MusicId &music_id) {
  *
  * When a music is playing, this function makes it update.
  */
+
 void Music::update() {
 
   if (!is_initialized()) {
     return;
   }
-
-  if (current_music != NULL) {
-    current_music->update_playing();
-  }
-}
-
-/**
- * @brief Updates this music when it is playing.
- *
- * This function handles the double buffering.
- */
-void Music::update_playing() {
-
-  // get the empty buffers
-  ALint nb_empty;
-  alGetSourcei(source, AL_BUFFERS_PROCESSED, &nb_empty);
-
-  // refill them
-  for (int i = 0; i < nb_empty; i++) {
-    ALuint buffer;
-    alSourceUnqueueBuffers(source, 1, &buffer); // unqueue the buffer
-
-    // fill it by decoding more data
-    switch (format) {
-
-      case SPC:
-	decode_spc(buffer, 4096);
-	break;
-
-      case IT:
-        decode_it(buffer, 4096);
-        break;
-
-      case OGG:
-	decode_ogg(buffer, 4096);
-	break;
-
-    }
-    alSourceQueueBuffers(source, 1, &buffer);   // queue it again
-  }
-
-  ALint status;
-  alGetSourcei(source, AL_SOURCE_STATE, &status);
-
-  if (status != AL_PLAYING) {
-    alSourcePlay(source);
-  }
-}
-
-/**
- * @brief Decodes a chunk of SPC data into PCM data for the current music.
- * @param destination_buffer the destination buffer to write
- * @param nb_samples number of samples to write
- */
-void Music::decode_spc(ALuint destination_buffer, ALsizei nb_samples) {
-
-  // decode the SPC data
-  ALushort *raw_data = new ALushort[nb_samples];
-  spc_decoder->decode((int16_t*) raw_data, nb_samples);
-
-  // put this decoded data into the buffer
-  alBufferData(destination_buffer, AL_FORMAT_STEREO16, raw_data, nb_samples * 2, 32000);
-
-  delete[] raw_data;
-
-  int error = alGetError();
-  Debug::check_assertion(error == AL_NO_ERROR,
-      StringConcat() << "Failed to fill the audio buffer with decoded SPC data for music file '" << file_name << ": error " << error);
-}
-
-/**
- * @brief Decodes a chunk of IT data into PCM data for the current music.
- * @param destination_buffer the destination buffer to write
- * @param nb_samples number of samples to write
- */
-void Music::decode_it(ALuint destination_buffer, ALsizei nb_samples) {
-
-  // decode the IT data
-  ALushort *raw_data = new ALushort[nb_samples];
-  it_decoder->decode(raw_data, nb_samples);
-
-  // put this decoded data into the buffer
-  alBufferData(destination_buffer, AL_FORMAT_STEREO16, raw_data, nb_samples, 44100);
-
-  delete[] raw_data;
-
-  int error = alGetError();
-  Debug::check_assertion(error == AL_NO_ERROR,
-      StringConcat() << "Failed to fill the audio buffer with decoded IT data for music file '" << file_name << ": error " << error);
-}
-
-/**
- * @brief Decodes a chunk of OGG data into PCM data for the current music.
- * @param destination_buffer the destination buffer to write
- * @param nb_samples number of samples to write
- */
-void Music::decode_ogg(ALuint destination_buffer, ALsizei nb_samples) {
-
-  // read the encoded music properties
-  vorbis_info* info = ov_info(&ogg_file, -1);
-  ALsizei sample_rate = info->rate;
-
-  ALenum al_format = AL_NONE;
-  if (info->channels == 1) {
-    al_format = AL_FORMAT_MONO16;
-  }
-  else if (info->channels == 2) {
-    al_format = AL_FORMAT_STEREO16;
-  }
-
-  // decode the OGG data
-  ALshort* raw_data = new ALshort[nb_samples * info->channels];
-  int bitstream;
-  long bytes_read;
-  long total_bytes_read = 0;
-  long remaining_bytes = nb_samples * info->channels * sizeof(ALshort);
-  do {
-    bytes_read = ov_read(&ogg_file, ((char*) raw_data) + total_bytes_read, remaining_bytes, 0, 2, 1, &bitstream);
-    if (bytes_read < 0) {
-      std::cout << "Error while decoding ogg chunk: " << bytes_read << std::endl;
-    }
-    else {
-      total_bytes_read += bytes_read;
-      remaining_bytes -= bytes_read;
-    }
-  }
-  while (remaining_bytes > 0 && bytes_read > 0);
-
-  // put this decoded data into the buffer
-  alBufferData(destination_buffer, al_format, raw_data, total_bytes_read, sample_rate);
-
-  delete[] raw_data;
-
-  int error = alGetError();
-  Debug::check_assertion(error == AL_NO_ERROR,
-      StringConcat() << "Failed to fill the audio buffer with decoded OGG data for music file '" << file_name << ": error " << error);
 }
 
 /**
@@ -365,85 +214,22 @@ void Music::decode_ogg(ALuint destination_buffer, ALsizei nb_samples) {
  */
 bool Music::start() {
 
-  if (!is_initialized()) {
+  if (!is_initialized()||Music::volume==0.0) {
     return false;
   }
 
   Debug::check_assertion(current_music == NULL, StringConcat() << "Cannot play music file '" << file_name << "': a music is already playing");
 
-  bool success = true;
-
-  // create the two buffers and the source
-  alGenBuffers(nb_buffers, buffers);
-  alGenSources(1, &source);
-  alSourcef(source, AL_GAIN, volume);
-
-  // load the music into memory
-  size_t sound_size;
-  char *sound_data;
-  switch (format) {
-
-    case SPC:
-
-      FileTools::data_file_open_buffer(file_name, &sound_data, &sound_size);
-
-      // load the SPC data into the SPC decoding library
-      spc_decoder->load((int16_t*) sound_data, sound_size);
-      FileTools::data_file_close_buffer(sound_data);
-
-      for (int i = 0; i < nb_buffers; i++) {
-        decode_spc(buffers[i], 4096);
-      }
-      break;
-
-    case IT:
-
-      FileTools::data_file_open_buffer(file_name, &sound_data, &sound_size);
-
-      // load the IT data into the IT decoding library
-      it_decoder->load(sound_data, sound_size);
-      FileTools::data_file_close_buffer(sound_data);
-
-      for (int i = 0; i < nb_buffers; i++) {
-        decode_it(buffers[i], 4096);
-      }
-      break;
-
-    case OGG:
-
-      ogg_mem.position = 0;
-      FileTools::data_file_open_buffer(file_name, &ogg_mem.data, &ogg_mem.size);
-      // now, ogg_mem contains the encoded data
+  bool success = false;
 
-      int error = ov_open_callbacks(&ogg_mem, &ogg_file, NULL, 0, Sound::ogg_callbacks);
-      if (error) {
-        std::cout << "Cannot load music file from memory: error " << error << std::endl;
-      }
-      else {
-        for (int i = 0; i < nb_buffers; i++) {
-          decode_ogg(buffers[i], 4096);
-        }
-      }
-      break;
+  if (mus == NULL)
+    mus = Mix_LoadMUS_RW(PHYSFSRWOPS_openRead(file_name.c_str()));
+  
+  if (mus != NULL) {
+    Mix_PlayMusic(mus, -1); 
+    success = true;
   }
 
-  // start the streaming
-  alSourceQueueBuffers(source, nb_buffers, buffers);
-  int error = alGetError();
-  if (error != AL_NO_ERROR) {
-    std::cerr << "Cannot initialize buffers for music '" << file_name << "': error " << error << std::endl;
-    success = false;
-  }
-/*  else {
-    alSourcePlay(source);
-    int error = alGetError();
-    if (error != AL_NO_ERROR) {
-      std::cerr << "Cannot play music '" << file_name << "': error " << error << std::endl;
-      success = false;
-    }
-  }*/
-
-  // now the update() function will take care of filling the buffers
   current_music = this;
   return success;
 }
@@ -461,38 +247,8 @@ void Music::stop() {
     return;
   }
 
-  // empty the source
-  alSourceStop(source);
-  ALint nb_queued;
-  ALuint buffer;
-  alGetSourcei(source, AL_BUFFERS_QUEUED, &nb_queued);
-  for (int i = 0; i < nb_queued; i++) {
-    alSourceUnqueueBuffers(source, 1, &buffer);
-  }
-  alSourcei(source, AL_BUFFER, 0);
-
-  // delete the source
-  alDeleteSources(1, &source);
-
-  // delete the buffers
-  alDeleteBuffers(nb_buffers, buffers);
-
+  Mix_HaltMusic();
   current_music = NULL;
-
-  switch (format) {
-
-    case SPC:
-      break;
-
-    case IT:
-      it_decoder->unload();
-      break;
-
-    case OGG:
-      ov_clear(&ogg_file);
-      FileTools::data_file_close_buffer(ogg_mem.data);
-      break;
-  }
 }
 
 /**
@@ -505,9 +261,7 @@ bool Music::is_paused() {
     return false;
   }
 
-  ALint status;
-  alGetSourcei(source, AL_SOURCE_STATE, &status);
-  return status == AL_PAUSED;
+  return false;
 }
 
 /**
@@ -520,11 +274,11 @@ void Music::set_paused(bool pause) {
     return;
   }
 
-  if (pause) {
+/*  if (pause) {
     alSourcePause(source);
   }
   else {
     alSourcePlay(source);
-  }
+  }*/
 }
 
diff --git a/src/lowlevel/Random.cpp b/src/lowlevel/Random.cpp
index db79242..c43a231 100644
--- a/src/lowlevel/Random.cpp
+++ b/src/lowlevel/Random.cpp
@@ -41,7 +41,7 @@ void Random::quit() {
  * @return a random integer number in [0, x[
  */
 int Random::get_number(unsigned int x) {
-  return (int) ((double) x * rand() / (RAND_MAX + 1.0));
+  return (int) ((float) x * rand() / (RAND_MAX + 1.0));
 }
 
 /**
diff --git a/src/lowlevel/Sound.cpp b/src/lowlevel/Sound.cpp
index 04e164d..ca0b691 100644
--- a/src/lowlevel/Sound.cpp
+++ b/src/lowlevel/Sound.cpp
@@ -24,26 +24,22 @@
 #include "lowlevel/FileTools.h"
 #include "lowlevel/Debug.h"
 #include "lowlevel/StringConcat.h"
+#include "lowlevel/physfsrwops.h"
 #include "Configuration.h"
 
-ALCdevice * Sound::device = NULL;
-ALCcontext * Sound::context = NULL;
+#include <SDL/SDL.h>
+#include <SDL/SDL_mixer.h>
+
 bool Sound::initialized = false;
 float Sound::volume = 1.0;
 std::list<Sound*> Sound::current_sounds;
 std::map<SoundId,Sound> Sound::all_sounds;
-ov_callbacks Sound::ogg_callbacks = {
-    cb_read,
-    NULL,
-    NULL,
-    NULL
-};
 
 /**
  * @brief Empty constructor.
  */
 Sound::Sound():
-  id(""), buffer(AL_NONE) {
+  snd(NULL), id("") {
 
 }
 
@@ -53,7 +49,7 @@ Sound::Sound():
  * without the extension (.ogg is added automatically)
  */
 Sound::Sound(const SoundId &sound_id):
-  id(sound_id), buffer(AL_NONE) {
+  snd(NULL), id(sound_id) {
 }
 
 /**
@@ -64,14 +60,14 @@ Sound::~Sound() {
   if (is_initialized()) {
 
     // stop the sources where this buffer is attached
-    std::list<ALuint>::iterator it;
+/*    std::list<ALuint>::iterator it;
     for (it = sources.begin(); it != sources.end(); it++) {
       ALuint source = (*it);
       alSourceStop(source);
       alSourcei(source, AL_BUFFER, 0);
       alDeleteSources(1, &source);
     }
-    alDeleteBuffers(1, &buffer);
+    alDeleteBuffers(1, &buffer);*/
     current_sounds.remove(this);
   }
 }
@@ -98,42 +94,11 @@ void Sound::initialize(int argc, char **argv) {
     return;
   }
 
-  // initialize OpenAL
-
-/*
-  const ALCchar* devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
-  while (devices[0] != '\0') {
-    std::cout << "Audio device: " << devices << std::endl;
-    devices += strlen(devices) + 1;
-  }
-  */
-
-  device = alcOpenDevice(NULL);
-//  device = alcOpenDevice("ALSA Software on ATI IXP");
-  if (!device) {
-    std::cout << "Cannot open audio device" << std::endl;
-    return;
-  }
-
-  ALCint attr[] = { ALC_FREQUENCY, 32000, 0 }; // 32 KHz is the SPC output sampling rate
-  context = alcCreateContext(device, attr);
-  if (!context) {
-    std::cout << "Cannot create audio context" << std::endl;
-    alcCloseDevice(device);
-    return;
-  }
-  if (!alcMakeContextCurrent(context)) {
-    std::cout << "Cannot activate audio context" << std::endl;
-    alcDestroyContext(context);
-    alcCloseDevice(device);
-    return;
-  }
+  SDL_InitSubSystem(SDL_INIT_AUDIO);
+  Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 4096);
 
   initialized = true;
 
-  // get the sound effects volume from the configuration file
-  set_volume(Configuration::get_value("sound_volume", 100));
-
   // initialize the music system
   Music::initialize();
 }
@@ -147,29 +112,15 @@ void Sound::quit() {
 
   if (is_initialized()) {
 
-/*
-    // stop the sound sources
-    ALuint source;
-    std::list<ALuint>::iterator it;
-    for (it = all_sources.begin(); it != all_sources.end(); it++) {
-      source = (*it);
-      alSourcei(source, AL_BUFFER, 0);
-      alDeleteSources(1, &source);
-    }
-*/
     // uninitialize the music subsystem
     Music::quit();
 
     // clear the sounds
     all_sounds.clear();
 
-    // uninitialize OpenAL
+    // uninitialize SDL_Mixer
 
-    alcMakeContextCurrent(NULL);
-    alcDestroyContext(context);
-    context = NULL;
-    alcCloseDevice(device);
-    device = NULL;
+    Mix_CloseAudio();
 
     initialized = false;
   }
@@ -188,37 +139,34 @@ bool Sound::is_initialized() {
  */
 void Sound::load_all() {
 
-  if (is_initialized()) {
-
-    // open the resource database file
-    const std::string file_name = "project_db.dat";
-    std::istream& database_file = FileTools::data_file_open(file_name);
-    std::string line;
+  // open the resource database file
+  const std::string file_name = "project_db.dat";
+  std::istream& database_file = FileTools::data_file_open(file_name);
+  std::string line;
 
-    // read each animation
-    while (std::getline(database_file, line)) {
+  // read each animation
+  while (std::getline(database_file, line)) {
 
-      if (line.size() == 0) {
-        continue;
-      }
+    if (line.size() == 0) {
+      continue;
+    }
 
-      int resource_type;
-      std::string resource_id, resource_name;
-      std::istringstream iss(line);
-      FileTools::read(iss, resource_type);
-      FileTools::read(iss, resource_id);
-      FileTools::read(iss, resource_name);
+    int resource_type;
+    std::string resource_id, resource_name;
+    std::istringstream iss(line);
+    FileTools::read(iss, resource_type);
+    FileTools::read(iss, resource_id);
+    FileTools::read(iss, resource_name);
 
-      if (resource_type == 4) { // it's a sound
+    if (resource_type == 4) { // it's a sound
 
-        if (all_sounds.count(resource_id) == 0) {
-          all_sounds[resource_id] = Sound(resource_id);
-          all_sounds[resource_id].load();
-        }
+      if (all_sounds.count(resource_id) == 0) {
+        all_sounds[resource_id] = Sound(resource_id);
+        all_sounds[resource_id].load();
       }
     }
-    FileTools::data_file_close(database_file);
   }
+  FileTools::data_file_close(database_file);
 }
 
 /**
@@ -264,6 +212,7 @@ void Sound::set_volume(int volume) {
 
   Configuration::set_value("sound_volume", volume);
   Sound::volume = volume / 100.0;
+  Mix_Volume(-1, volume);
 }
 
 /**
@@ -272,48 +221,11 @@ void Sound::set_volume(int volume) {
  * This function is called repeatedly by the game.
  */
 void Sound::update() {
-
-  // update the playing sounds
-  Sound *sound;
-  std::list<Sound*> sounds_to_remove;
-  std::list<Sound*>::iterator it;
-  for (it = current_sounds.begin(); it != current_sounds.end(); it++) {
-    sound = *it;
-    if (!sound->update_playing()) {
-      sounds_to_remove.push_back(sound);
-    }
-  }
-
-  for (it = sounds_to_remove.begin(); it != sounds_to_remove.end(); it++) {
-    sound = *it;
-    current_sounds.remove(sound);
-  }
-
   // also update the music
   Music::update();
 }
 
 /**
- * @brief Updates this sound when it is playing.
- * @return true if the sound is still playing, false if it is finished.
- */
-bool Sound::update_playing() {
-
-  // see whether a source playing this sound has finished playing
-  ALuint source = *sources.begin();
-  ALint status;
-  alGetSourcei(source, AL_SOURCE_STATE, &status);
-
-  if (status != AL_PLAYING) {
-    sources.pop_front();
-    alSourcei(source, AL_BUFFER, 0);
-    alDeleteSources(1, &source);
-  }
-
-  return sources.size() != 0;
-}
-
-/**
  * @brief Loads and decodes the sound into memory.
  */
 void Sound::load() {
@@ -322,12 +234,9 @@ void Sound::load() {
   if (id.find(".") == std::string::npos) {
     file_name += ".ogg";
   }
-
-  // create an OpenAL buffer with the sound decoded by the library
-  buffer = decode_file(file_name);
-
-  if (buffer == AL_NONE) {
-    std::cerr << "Sound '" << file_name << "' will not be played" << std::endl;
+  snd = Mix_LoadWAV_RW(PHYSFSRWOPS_openRead(file_name.c_str()),1);
+  if(!snd) {
+    printf("Mix_LoadWAV_RW: %s\n", Mix_GetError());
   }
 }
 
@@ -340,141 +249,13 @@ bool Sound::start() {
   bool success = false;
 
   if (is_initialized()) {
-
-    if (buffer == AL_NONE) { // first time: load and decode the file
+    if (snd == NULL)
       load();
-    }
-
-    if (buffer != AL_NONE) {
-
-      // create a source
-      ALuint source;
-      alGenSources(1, &source);
-      alSourcei(source, AL_BUFFER, buffer);
-      alSourcef(source, AL_GAIN, volume);
 
-      // play the sound
-      int error = alGetError();
-      if (error != AL_NO_ERROR) {
-	std::cerr << "Cannot attach buffer " << buffer << " to the source to play sound: error " << error << std::endl;
-	alDeleteSources(1, &source);
-      }
-      else {
-	sources.push_back(source);
-	current_sounds.remove(this); // to avoid duplicates
-	current_sounds.push_back(this);
-	alSourcePlay(source);
-	error = alGetError();
-	if (error != AL_NO_ERROR) {
-	  std::cerr << "Cannot play sound: error " << error << std::endl;
-	}
-	else {
-	  success = true;
-	}
-      }
+    if (snd != NULL) {
+      Mix_PlayChannel(-1, snd, 0);
+      success = true;
     }
   }
   return success;
 }
-
-/**
- * @brief Loads the specified sound file and decodes its content into an OpenAL buffer.
- * @param file_name name of the file to open
- * @return the buffer created, or AL_NONE if the sound could not be loaded
- */
-ALuint Sound::decode_file(const std::string &file_name) {
-
-  ALuint buffer = AL_NONE;
-
-  // load the sound file
-  SoundFromMemory mem;
-  mem.position = 0;
-  FileTools::data_file_open_buffer(file_name, &mem.data, &mem.size);
-
-  OggVorbis_File file;
-  int error = ov_open_callbacks(&mem, &file, NULL, 0, ogg_callbacks);
-
-  if (error) {
-    std::cout << "Cannot load sound file from memory: error " << error << std::endl;
-  }
-  else {
-
-    // read the encoded sound properties
-    vorbis_info* info = ov_info(&file, -1);
-    ALsizei sample_rate = info->rate;
-
-    ALenum format = AL_NONE;
-    if (info->channels == 1) {
-      format = AL_FORMAT_MONO16;
-    }
-    else if (info->channels == 2) {
-      format = AL_FORMAT_STEREO16;
-    }
-
-    if (format == AL_NONE) {
-      std::cout << "Invalid audio format" << std::endl;
-    }
-    else {
-
-      // decode the sound with vorbisfile
-      std::vector<char> samples;
-      int bitstream;
-      long bytes_read;
-      long total_bytes_read = 0;
-      char samples_buffer[4096];
-      do {
-        bytes_read = ov_read(&file, samples_buffer, 4096, 0, 2, 1, &bitstream);
-        if (bytes_read < 0) {
-          std::cout << "Error while decoding ogg chunk: " << bytes_read << std::endl;
-        }
-        else {
-          total_bytes_read += bytes_read;
-          if (format == AL_FORMAT_STEREO16) {
-            samples.insert(samples.end(), samples_buffer, samples_buffer + bytes_read);
-          }
-          else {
-            // mono sound files make no sound on some machines
-            // workaround: convert them on-the-fly into stereo sounds
-            // TODO find a better solution
-            for (int i = 0; i < bytes_read; i += 2) {
-              samples.insert(samples.end(), samples_buffer + i, samples_buffer + i + 2);
-              samples.insert(samples.end(), samples_buffer + i, samples_buffer + i + 2);
-            }
-            total_bytes_read += bytes_read;
-          }
-        }
-      }
-      while (bytes_read > 0);
-
-      // copy the samples into an OpenAL buffer
-      alGenBuffers(1, &buffer);
-      alBufferData(buffer, AL_FORMAT_STEREO16, (ALshort*) &samples[0], total_bytes_read, sample_rate);
-      if (alGetError() != AL_NO_ERROR) {
-        std::cout << "Cannot copy the sound samples into buffer " << buffer << "\n";
-        buffer = AL_NONE;
-      }
-    }
-    ov_clear(&file);
-  }
-
-  FileTools::data_file_close_buffer(mem.data);
-
-  return buffer;
-}
-
-
-// io functions to load the encoded sound from memory
-
-size_t Sound::cb_read(void* ptr, size_t size, size_t nmemb, void* datasource) {
-
-  SoundFromMemory* mem = (SoundFromMemory*) datasource;
-  size_t nb_bytes = nmemb;
-  if (mem->position + nb_bytes >= mem->size) {
-    nb_bytes = mem->size - mem->position;
-  }
-  memcpy(ptr, mem->data + mem->position, nb_bytes);
-  mem->position += nb_bytes;
-
-  return nb_bytes;
-}
-
diff --git a/src/lowlevel/VideoManager.cpp b/src/lowlevel/VideoManager.cpp
index 9084d30..df7a85b 100644
--- a/src/lowlevel/VideoManager.cpp
+++ b/src/lowlevel/VideoManager.cpp
@@ -26,6 +26,7 @@
 VideoManager *VideoManager::instance = NULL;
 
 Rectangle VideoManager::default_mode_sizes[] = {
+//#ifndef CAANOO
   Rectangle(0, 0, 640, 480),         // WINDOWED_STRETCHED
   Rectangle(0, 0, 640, 480),         // WINDOWED_SCALE2X
   Rectangle(0, 0, 320, 240),         // WINDOWED_NORMAL
@@ -35,6 +36,9 @@ Rectangle VideoManager::default_mode_sizes[] = {
   Rectangle(0, 0,   0,   0),         // FULLSCREEN_SCALE2X_WIDE
   Rectangle(0, 0, 640, 480),         // FULLSCREEN_CENTERED
   Rectangle(0, 0, 640, 400),         // FULLSCREEN_CENTERED_WIDE
+/*#else
+  Rectangle(0, 0, 320, 240)	     // 320x240 is the only mode the Caanoo support
+#endif*/
 };
 
 /**
@@ -93,7 +97,7 @@ VideoManager::VideoManager(bool disable_window):
   for (int i = 0; i < NB_MODES; i++) {
     mode_sizes[i] = default_mode_sizes[i];
   }
-
+#ifndef CAANOO
   int flags = SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN;
   if (SDL_VideoModeOK(768, 480, 32, flags)) {
     mode_sizes[FULLSCREEN_WIDE].set_size(768, 480);
@@ -105,6 +109,7 @@ VideoManager::VideoManager(bool disable_window):
     mode_sizes[FULLSCREEN_SCALE2X_WIDE].set_size(720, 480);
     dst_position_wide.set_xy(40, 0);
   }
+#endif
 
   /* debug (see the fullscreen video modes supported)
      SDL_Rect **rects = SDL_ListModes(NULL, flags);
@@ -159,11 +164,15 @@ bool VideoManager::is_fullscreen(VideoMode mode) {
  */
 void VideoManager::switch_video_mode() {
 
+#ifdef CAANOO
+  set_video_mode(WINDOWED_NORMAL);
+#else
   VideoMode mode = video_mode;
   do {
     mode = (VideoMode) ((mode + 1) % NB_MODES);
   } while (!is_mode_supported(mode));
   set_video_mode(mode);
+#endif
 }
 
 /**
@@ -174,6 +183,9 @@ void VideoManager::switch_video_mode() {
  */
 void VideoManager::set_initial_video_mode() {
 
+#ifdef CAANOO
+  set_video_mode(WINDOWED_NORMAL);
+#else
   int value = Configuration::get_value("video_mode", -1);
 
   if (value < 0 || value >= NB_MODES) {
@@ -182,13 +194,18 @@ void VideoManager::set_initial_video_mode() {
   else {
     set_video_mode((VideoMode) value);
   }
+#endif
 }
 
 /**
  * @brief Sets the default video mode.
  */
 void VideoManager::set_default_video_mode() {
+#ifdef CAANOO
+  set_video_mode(WINDOWED_NORMAL);
+#else
   set_video_mode(WINDOWED_STRETCHED);
+#endif
 }
 
 /**
@@ -202,6 +219,11 @@ void VideoManager::set_video_mode(VideoMode mode) {
 
   const Rectangle &size = mode_sizes[mode];
 
+#ifdef CAANOO
+  int flags = SDL_HWSURFACE;
+  int show_cursor = SDL_DISABLE;
+  width = 320;
+#else
   int flags = SDL_HWSURFACE | SDL_DOUBLEBUF;
   int show_cursor;
   if (is_fullscreen(mode)) {
@@ -222,10 +244,17 @@ void VideoManager::set_video_mode(VideoMode mode) {
     width = 640;
     offset = 0;
   }
+#endif
   end_row_increment = 2 * offset + width;
 
+printf("w=%d, h=%d\n", size.get_width(), size.get_height());
   if (!disable_window) {
+#ifdef CAANOO
+    SDL_Surface *screen_internal_surface = SDL_SetVideoMode(320,240,16, flags);
+#else
     SDL_Surface *screen_internal_surface = SDL_SetVideoMode(size.get_width(), size.get_height(), 32, flags);
+#endif
+
 
     Debug::check_assertion(screen_internal_surface != NULL, StringConcat() << "Cannot create the video surface for mode " << mode);
 
diff --git a/src/lua/MainAPI.cpp b/src/lua/MainAPI.cpp
index 6eea1da..71844ed 100644
--- a/src/lua/MainAPI.cpp
+++ b/src/lua/MainAPI.cpp
@@ -605,7 +605,7 @@ int Script::main_api_rectilinear_movement_create(lua_State *l) {
   Script *script;
   called_by_script(l, 2, &script);
   int speed = luaL_checkinteger(l, 1);
-  double angle = luaL_checknumber(l, 2);
+  float angle = luaL_checknumber(l, 2);
 
   RectilinearMovement *movement = new RectilinearMovement(false);
   movement->set_speed(speed);
@@ -631,7 +631,7 @@ int Script::main_api_temporal_movement_create(lua_State *l) {
   Script *script;
   called_by_script(l, 3, &script);
   int speed = luaL_checkinteger(l, 1);
-  double angle = luaL_checknumber(l, 2);
+  float angle = luaL_checknumber(l, 2);
   uint32_t duration = luaL_checkinteger(l, 3);
 
   TemporalMovement *movement = new TemporalMovement(speed, angle, duration);
@@ -743,7 +743,7 @@ int Script::main_api_movement_set_property(lua_State *l) {
     value = lua_tostring(l, 3);
   }
   else if (lua_isnumber(l, 3)) {
-    double v = lua_tointeger(l, 3);
+    float v = lua_tointeger(l, 3);
     std::ostringstream oss;
     if (std::fabs(v - (int) v) < 1e-6) {
       oss << (int) v;
@@ -812,7 +812,7 @@ int Script::main_api_get_angle(lua_State *l) {
   int x2 = luaL_checkinteger(l, 3);
   int y2 = luaL_checkinteger(l, 4);
 
-  double angle = Geometry::get_angle(x1, y1, x2, y2);
+  float angle = Geometry::get_angle(x1, y1, x2, y2);
   lua_pushnumber(l, angle);
 
   return 1;
diff --git a/src/menus/SelectionMenu.cpp b/src/menus/SelectionMenu.cpp
index f697c7c..06bcff4 100644
--- a/src/menus/SelectionMenu.cpp
+++ b/src/menus/SelectionMenu.cpp
@@ -75,7 +75,7 @@ SelectionMenu::SelectionMenu(Solarus &solarus):
   title_text->set_font("fixed");
 
   // music
-  Music::play("game_over.spc");
+  Music::play("game_over.IT");
 
   // transitions
   transition = Transition::create(Transition::FADE, Transition::IN);
diff --git a/src/menus/TitleScreen.cpp b/src/menus/TitleScreen.cpp
index a649446..3af2dc5 100644
--- a/src/menus/TitleScreen.cpp
+++ b/src/menus/TitleScreen.cpp
@@ -115,6 +115,7 @@ void TitleScreen::display(Surface *destination_surface) {
   switch (current_phase) {
 
   case PHASE_BLACK_SCREEN:
+    destination_surface->fill_with_color(Color::get_black());
     // nothing to display
     break;
 
@@ -206,7 +207,7 @@ void TitleScreen::init_phase_title() {
 
   current_phase = PHASE_TITLE;
 
-  Music::play("title_screen.spc");
+  Music::play("title_screen.IT");
 
   const std::string &time_of_day_name = time_of_day_strings[time_of_day];
   std::string background_img_name = (std::string) "menus/title_" + time_of_day_name + "_background.png";
diff --git a/src/movements/RandomMovement.cpp b/src/movements/RandomMovement.cpp
index 7cb25a7..6ac8403 100644
--- a/src/movements/RandomMovement.cpp
+++ b/src/movements/RandomMovement.cpp
@@ -74,7 +74,7 @@ void RandomMovement::set_max_distance(int max_distance) {
  */
 void RandomMovement::set_next_direction() {
 
-  double angle;
+  float angle;
   if (get_entity() == NULL
       || max_distance == 0 // means no limit
       || bounds.contains(get_x(), get_y())) {
diff --git a/src/movements/RectilinearMovement.cpp b/src/movements/RectilinearMovement.cpp
index dfad0a3..005dcc8 100644
--- a/src/movements/RectilinearMovement.cpp
+++ b/src/movements/RectilinearMovement.cpp
@@ -50,7 +50,7 @@ RectilinearMovement::~RectilinearMovement() {
  * @brief Returns the x speed of the object.
  * @return the x speed of the entity, between -100 and 100
  */
-double RectilinearMovement::get_x_speed() {
+float RectilinearMovement::get_x_speed() {
   return x_speed;
 }
 
@@ -58,7 +58,7 @@ double RectilinearMovement::get_x_speed() {
  * @brief Returns the y speed of the object.
  * @return the y speed of the entity, between -100 and 100
  */
-double RectilinearMovement::get_y_speed() {
+float RectilinearMovement::get_y_speed() {
   return y_speed;
 }
 
@@ -69,7 +69,7 @@ double RectilinearMovement::get_y_speed() {
  *
  * @return the speed in pixels per second
  */
-double RectilinearMovement::get_speed() {
+float RectilinearMovement::get_speed() {
   return std::sqrt(x_speed * x_speed + y_speed * y_speed);
 }
 
@@ -77,7 +77,7 @@ double RectilinearMovement::get_speed() {
  * @brief Sets the x speed.
  * @param x_speed the x speed of the object in pixels per second
  */
-void RectilinearMovement::set_x_speed(double x_speed) {
+void RectilinearMovement::set_x_speed(float x_speed) {
 
   if (std::fabs(x_speed) <= 1E-6) {
     x_speed = 0;
@@ -112,7 +112,7 @@ void RectilinearMovement::set_x_speed(double x_speed) {
  * @brief Sets the y speed.
  * @param y_speed the y speed of the object in pixels per second
  */
-void RectilinearMovement::set_y_speed(double y_speed) {
+void RectilinearMovement::set_y_speed(float y_speed) {
 
   if (std::fabs(y_speed) <= 1E-6) {
     y_speed = 0;
@@ -150,14 +150,14 @@ void RectilinearMovement::set_y_speed(double y_speed) {
  *
  * @param speed the new speed
  */
-void RectilinearMovement::set_speed(double speed) {
+void RectilinearMovement::set_speed(float speed) {
 
   if (x_speed == 0 && y_speed == 0) {
     x_speed = 1;
   }
 
   // compute the new speed vector
-  double old_angle = this->angle;
+  float old_angle = this->angle;
   set_x_speed(speed * std::cos(old_angle));
   set_y_speed(-speed * std::sin(old_angle));
   this->angle = old_angle;
@@ -180,7 +180,7 @@ bool RectilinearMovement::is_started() {
  */
 void RectilinearMovement::stop() {
 
-  double old_angle = this->angle;
+  float old_angle = this->angle;
   set_x_speed(0);
   set_y_speed(0);
   set_x_move(0);
@@ -226,7 +226,7 @@ void RectilinearMovement::set_next_move_date_y(uint32_t next_move_date_y) {
  * @brief Computes and returns the direction of the speed vector.
  * @return the current angle of the speed vector in degrees
  */
-double RectilinearMovement::get_angle() {
+float RectilinearMovement::get_angle() {
 
   return angle;
 }
@@ -240,10 +240,10 @@ double RectilinearMovement::get_angle() {
  *
  * @param angle the new movement direction in radians
  */
-void RectilinearMovement::set_angle(double angle) {
+void RectilinearMovement::set_angle(float angle) {
 
   if (!is_stopped()) {
-    double speed = get_speed();
+    float speed = get_speed();
     set_x_speed(speed * std::cos(angle));
     set_y_speed(-speed * std::sin(angle));
   }
@@ -465,7 +465,7 @@ void RectilinearMovement::set_property(const std::string &key, const std::string
     set_speed(speed);
   }
   else if (key == "angle") {
-    double angle;
+    float angle;
     iss >> angle;
     set_angle(angle);
   }
diff --git a/src/movements/TargetMovement.cpp b/src/movements/TargetMovement.cpp
index d9eb713..b08e024 100644
--- a/src/movements/TargetMovement.cpp
+++ b/src/movements/TargetMovement.cpp
@@ -138,7 +138,7 @@ void TargetMovement::recompute_movement() {
   if (get_x() != target_x || get_y() != target_y) {
     finished = false;
 
-    double angle = Geometry::get_angle(get_x(), get_y(), target_x, target_y);
+    float angle = Geometry::get_angle(get_x(), get_y(), target_x, target_y);
 
     int dx = target_x - get_x();
     int dy = target_y - get_y();
diff --git a/src/movements/TemporalMovement.cpp b/src/movements/TemporalMovement.cpp
index 9ed820d..4d7191a 100644
--- a/src/movements/TemporalMovement.cpp
+++ b/src/movements/TemporalMovement.cpp
@@ -27,7 +27,7 @@
  * @param duration duration of the movement in milliseconds
  * @param smooth true to make the movement smooth
  */
-TemporalMovement::TemporalMovement(int speed, double angle, uint32_t duration, bool smooth):
+TemporalMovement::TemporalMovement(int speed, float angle, uint32_t duration, bool smooth):
   SmoothMovement(smooth) {
   start(speed, angle, duration);
 }
@@ -43,7 +43,7 @@ TemporalMovement::TemporalMovement(int speed, double angle, uint32_t duration, b
 TemporalMovement::TemporalMovement(int speed, const Rectangle &source_xy, const Rectangle &target_xy, uint32_t duration, bool smooth):
   SmoothMovement(smooth) {
 
-  double angle = Geometry::get_angle(source_xy.get_x(), source_xy.get_y(), target_xy.get_x(), target_xy.get_y());
+  float angle = Geometry::get_angle(source_xy.get_x(), source_xy.get_y(), target_xy.get_x(), target_xy.get_y());
   start(speed, angle, duration);
 }
 
@@ -60,7 +60,7 @@ TemporalMovement::~TemporalMovement() {
  * @param angle angle of the movement in radians
  * @param duration duration of the movement in milliseconds
  */
-void TemporalMovement::start(int speed, double angle, uint32_t duration) {
+void TemporalMovement::start(int speed, float angle, uint32_t duration) {
 
   this->finished = false;
   this->duration = duration;
@@ -188,7 +188,7 @@ void TemporalMovement::set_property(const std::string &key, const std::string &v
     set_speed(speed);
   }
   else if (key == "angle") {
-    double angle;
+    float angle;
     iss >> angle;
     if (get_speed() == 0) {
       set_speed(1);
