Advertisement
Guest User

supertux-0.1.3-fp.patch

a guest
Dec 7th, 2014
452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 174.24 KB | None | 0 0
  1. diff -Naur supertux-0.1.3/src.bak/badguy.cpp supertux-0.1.3/src/badguy.cpp
  2. --- supertux-0.1.3/src.bak/badguy.cpp   2014-12-06 18:00:56.000000000 -0500
  3. +++ supertux-0.1.3/src/badguy.cpp   2014-12-07 13:03:28.000000000 -0500
  4. @@ -33,6 +33,7 @@
  5.  #include "tile.h"
  6.  #include "resources.h"
  7.  #include "sprite_manager.h"
  8. +#include "fpmath.h"
  9.  
  10.  Sprite* img_mriceblock_flat_left;
  11.  Sprite* img_mriceblock_flat_right;
  12. @@ -65,8 +66,6 @@
  13.  Sprite* img_snowball_squished_left;
  14.  Sprite* img_snowball_squished_right;
  15.  
  16. -#define BADGUY_WALK_SPEED .8f
  17. -
  18.  BadGuyKind  badguykind_from_string(const std::string& str)
  19.  {
  20.    if (str == "money" || str == "jumpy") // was money in old maps
  21. @@ -135,7 +134,7 @@
  22.      }
  23.  }
  24.  
  25. -BadGuy::BadGuy(float x, float y, BadGuyKind kind_, bool stay_on_platform_)
  26. +BadGuy::BadGuy(fp x, fp y, BadGuyKind kind_, bool stay_on_platform_)
  27.    : removable(false), squishcount(0)
  28.  {
  29.    base.x   = x;
  30. @@ -158,10 +157,10 @@
  31.    timer.init(true);
  32.  
  33.    if(kind == BAD_MRBOMB) {
  34. -    physic.set_velocity(-BADGUY_WALK_SPEED, 0);
  35. +    physic.set_velocity(-FP_BADGUY_WALK_SPEED, 0);
  36.      set_sprite(img_mrbomb_left, img_mrbomb_right);
  37.    } else if (kind == BAD_MRICEBLOCK) {
  38. -    physic.set_velocity(-BADGUY_WALK_SPEED, 0);
  39. +    physic.set_velocity(-FP_BADGUY_WALK_SPEED, 0);
  40.      set_sprite(img_mriceblock_left, img_mriceblock_right);
  41.    } else if(kind == BAD_JUMPY) {
  42.      set_sprite(img_jumpy_left_up, img_jumpy_left_up);
  43. @@ -174,7 +173,7 @@
  44.      physic.enable_gravity(false);
  45.      set_sprite(img_flame, img_flame);
  46.    } else if(kind == BAD_BOUNCINGSNOWBALL) {
  47. -    physic.set_velocity(-1.3, 0);
  48. +    physic.set_velocity(-FP_BOUNCINGSNOWBALL_SPEED, 0);
  49.      set_sprite(img_bouncingsnowball_left, img_bouncingsnowball_right);
  50.    } else if(kind == BAD_STALACTITE) {
  51.      physic.enable_gravity(false);
  52. @@ -186,10 +185,10 @@
  53.      set_sprite(img_flyingsnowball, img_flyingsnowball);
  54.      physic.enable_gravity(false);
  55.    } else if(kind == BAD_SPIKY) {
  56. -    physic.set_velocity(-BADGUY_WALK_SPEED, 0);
  57. +    physic.set_velocity(-FP_BADGUY_WALK_SPEED, 0);
  58.      set_sprite(img_spiky_left, img_spiky_right);
  59.    } else if(kind == BAD_SNOWBALL) {
  60. -    physic.set_velocity(-BADGUY_WALK_SPEED, 0);
  61. +    physic.set_velocity(-FP_BADGUY_WALK_SPEED, 0);
  62.      set_sprite(img_snowball_left, img_snowball_right);
  63.    }
  64.  
  65. @@ -197,14 +196,17 @@
  66.    if(kind != BAD_FLAME && kind != BAD_FISH && collision_object_map(base))
  67.      {
  68.        std::cout << "Warning: badguy started in wall: kind: " << badguykind_to_string(kind)
  69. -                << " pos: (" << base.x << ", " << base.y << ")" << std::endl;
  70. -      while(collision_object_map(base))
  71. -        --base.y;
  72. +                << " pos: (" << fp2float(base.x) << ", " << fp2float(base.y) << ")" << std::endl;
  73. +      while(collision_object_map(base)) {
  74. +       //FIXME: check use of --
  75. +        //--base.y;
  76. +        base.y -= int2fp(1);
  77. +      }
  78.      }
  79.  }
  80.  
  81.  void
  82. -BadGuy::action_mriceblock(double frame_ratio)
  83. +BadGuy::action_mriceblock(fp frame_ratio)
  84.  {
  85.    Player& tux = *World::current()->get_tux();
  86.  
  87. @@ -225,32 +227,32 @@
  88.        dir = tux.dir;
  89.        if(dir==RIGHT)
  90.          {
  91. -          base.x = tux.base.x + 16;
  92. -          base.y = tux.base.y + tux.base.height/1.5 - base.height;
  93. +          base.x = tux.base.x + int2fp(16);
  94. +          base.y = tux.base.y + tux.base.height*2/3 - base.height;
  95.          }
  96.        else /* facing left */
  97.          {
  98. -          base.x = tux.base.x - 16;
  99. -          base.y = tux.base.y + tux.base.height/1.5 - base.height;
  100. +          base.x = tux.base.x - int2fp(16);
  101. +          base.y = tux.base.y + tux.base.height*2/3 - base.height;
  102.          }
  103.        if(collision_object_map(base))
  104.          {
  105.            base.x = tux.base.x;
  106. -          base.y = tux.base.y + tux.base.height/1.5 - base.height;
  107. +          base.y = tux.base.y + tux.base.height*2/3 - base.height;
  108.          }
  109.  
  110.        if(tux.input.fire != DOWN) /* SHOOT! */
  111.          {
  112.            if(dir == LEFT)
  113. -            base.x -= 24;
  114. +            base.x -= int2fp(24);
  115.            else
  116. -            base.x += 24;
  117. +            base.x += int2fp(24);
  118.            old_base = base;
  119.  
  120.            mode=KICK;
  121.            tux.kick_timer.start(KICKING_TIME);
  122.            set_sprite(img_mriceblock_flat_left, img_mriceblock_flat_right);
  123. -          physic.set_velocity_x((dir == LEFT) ? -3.5 : 3.5);
  124. +          physic.set_velocity_x((dir == LEFT) ? -FP_MRICEBLOCK_SPEED : FP_MRICEBLOCK_SPEED);
  125.  #ifndef GP2X
  126.            play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
  127.  #else
  128. @@ -267,9 +269,9 @@
  129.          {
  130.  #ifndef GP2X
  131.            /* handle stereo sound (number 10 should be tweaked...)*/
  132. -          if (base.x < scroll_x + screen->w/2 - 10)
  133. +          if (base.x < scroll_x + int2fp(screen->w/2 - 10))
  134.              play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
  135. -          else if (base.x > scroll_x + screen->w/2 + 10)
  136. +          else if (base.x > scroll_x + int2fp(screen->w/2 + 10))
  137.              play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
  138.            else
  139.              play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
  140. @@ -286,7 +288,7 @@
  141.          {
  142.            mode = NORMAL;
  143.            set_sprite(img_mriceblock_left, img_mriceblock_right);
  144. -          physic.set_velocity( (dir == LEFT) ? -.8 : .8, 0);
  145. +          physic.set_velocity( (dir == LEFT) ? -FP_BADGUY_WALK_SPEED : FP_BADGUY_WALK_SPEED, 0);
  146.          }
  147.      }
  148.  }
  149. @@ -294,8 +296,8 @@
  150.  void
  151.  BadGuy::check_horizontal_bump(bool checkcliff)
  152.  {
  153. -    float halfheight = base.height / 2;
  154. -    if (dir == LEFT && issolid( base.x, (int) base.y + halfheight))
  155. +    fp halfheight = base.height / 2;
  156. +    if (dir == LEFT && issolid(fp2int(base.x), fp2int(base.y + halfheight)))
  157.      {
  158.          if (kind == BAD_MRICEBLOCK && mode == KICK)
  159.              World::current()->trybreakbrick(base.x, base.y + halfheight, false, dir);
  160. @@ -304,10 +306,10 @@
  161.          physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
  162.          return;
  163.      }
  164. -    if (dir == RIGHT && issolid( base.x + base.width, (int)base.y + halfheight))
  165. +    if (dir == RIGHT && issolid(fp2int(base.x + base.width), fp2int(base.y + halfheight)))
  166.      {
  167.          if (kind == BAD_MRICEBLOCK && mode == KICK)
  168. -            World::current()->trybreakbrick(base.x + base.width, (int) base.y + halfheight, false, dir);
  169. +            World::current()->trybreakbrick(base.x + base.width, base.y + halfheight, false, dir);
  170.          
  171.          dir = LEFT;
  172.          physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
  173. @@ -317,17 +319,17 @@
  174.      // don't check for cliffs when we're falling
  175.      if(!checkcliff)
  176.          return;
  177. -    if(!issolid(base.x + base.width/2, base.y + base.height))
  178. +    if(!issolid(fp2int(base.x + base.width/2), fp2int(base.y + base.height)))
  179.          return;
  180.      
  181. -    if(dir == LEFT && !issolid(base.x, (int) base.y + base.height + halfheight))
  182. +    if(dir == LEFT && !issolid(fp2int(base.x), fp2int(base.y + base.height + halfheight)))
  183.      {
  184.          dir = RIGHT;
  185.          physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
  186.          return;
  187.      }
  188. -    if(dir == RIGHT && !issolid(base.x + base.width,
  189. -                (int) base.y + base.height + halfheight))
  190. +    if(dir == RIGHT && !issolid(fp2int(base.x + base.width),
  191. +                fp2int(base.y + base.height + halfheight)))
  192.      {
  193.          dir = LEFT;
  194.          physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
  195. @@ -341,7 +343,7 @@
  196.    /* Fall if we get off the ground: */
  197.    if (dying != DYING_FALLING)
  198.      {
  199. -      if (!issolid(base.x+base.width/2, base.y + base.height))
  200. +      if (!issolid(fp2int(base.x+base.width/2), fp2int(base.y + base.height)))
  201.          {
  202.            // not solid below us? enable gravity
  203.            physic.enable_gravity(true);
  204. @@ -349,9 +351,12 @@
  205.        else
  206.          {
  207.            /* Land: */
  208. +          /* Always pull badguys out of the ground, otherwise they still
  209. +           * get stuck on slow systems. */
  210. +          base.y = int2fp((fp2int(base.y) / 32) * 32);
  211.            if (physic.get_velocity_y() < 0)
  212.              {
  213. -              base.y = int((base.y + base.height)/32) * 32 - base.height;
  214. +              //base.y = int2fp(fp2int(base.y + base.height)/32) * 32 - base.height;
  215.                physic.set_velocity_y(0);
  216.              }
  217.            // no gravity anymore please
  218. @@ -359,18 +364,18 @@
  219.  
  220.            if (stay_on_platform && mode == NORMAL)
  221.              {
  222. -              if (!issolid(base.x + ((dir == LEFT) ? 0 : base.width),
  223. -                           base.y + base.height))
  224. +              if (!issolid(fp2int(base.x + ((dir == LEFT) ? 0 : base.width)),
  225. +                           fp2int(base.y + base.height)))
  226.                  {
  227.                    if (dir == LEFT)
  228.                    {
  229.                      dir = RIGHT;
  230. -                    physic.set_velocity_x(fabsf(physic.get_velocity_x()));
  231. +                    physic.set_velocity_x(abs(physic.get_velocity_x()));
  232.                    }
  233.                    else
  234.                    {
  235.                      dir = LEFT;
  236. -                    physic.set_velocity_x(-fabsf(physic.get_velocity_x()));
  237. +                    physic.set_velocity_x(-abs(physic.get_velocity_x()));
  238.                    }
  239.                  }
  240.              }
  241. @@ -389,27 +394,25 @@
  242.  }
  243.  
  244.  void
  245. -BadGuy::action_jumpy(double frame_ratio)
  246. +BadGuy::action_jumpy(fp frame_ratio)
  247.  {
  248. -  const float vy = physic.get_velocity_y();
  249. +  const fp vy = physic.get_velocity_y();
  250.  
  251.    // XXX: These tests *should* use location from ground, not velocity
  252. -  if (fabsf(vy) > 5.6f)
  253. +  if (abs(vy) > FP_JUMP_SPEED_START)
  254.      set_sprite(img_jumpy_left_down, img_jumpy_left_down);
  255. -  else if (fabsf(vy) > 5.3f)
  256. +  else if (abs(vy) > FP_JUMP_SPEED_MIDDLE)
  257.      set_sprite(img_jumpy_left_middle, img_jumpy_left_middle);
  258.    else
  259.      set_sprite(img_jumpy_left_up, img_jumpy_left_up);
  260.  
  261.    Player& tux = *World::current()->get_tux();
  262.  
  263. -  static const float JUMPV = 6;
  264. -    
  265.    fall();
  266.    // jump when on ground
  267. -  if(dying == DYING_NOT && issolid(base.x, base.y+32))
  268. +  if(dying == DYING_NOT && issolid(fp2int(base.x), fp2int(base.y)+32))
  269.      {
  270. -      physic.set_velocity_y(JUMPV);
  271. +      physic.set_velocity_y(FP_JUMP_SPEED);
  272.        physic.enable_gravity(true);
  273.  
  274.        mode = JUMPY_JUMP;
  275. @@ -432,7 +435,7 @@
  276.  }
  277.  
  278.  void
  279. -BadGuy::action_mrbomb(double frame_ratio)
  280. +BadGuy::action_mrbomb(fp frame_ratio)
  281.  {
  282.    if (dying == DYING_NOT)
  283.      check_horizontal_bump(true);
  284. @@ -445,7 +448,7 @@
  285.  }
  286.  
  287.  void
  288. -BadGuy::action_bomb(double frame_ratio)
  289. +BadGuy::action_bomb(fp frame_ratio)
  290.  {
  291.    static const int TICKINGTIME = 1000;
  292.    static const int EXPLODETIME = 1000;
  293. @@ -463,10 +466,10 @@
  294.        timer.start(EXPLODETIME);
  295.  
  296.        /* play explosion sound */  // FIXME: is the stereo all right? maybe we should use player cordinates...
  297. -      if (base.x < scroll_x + screen->w/2 - 10)
  298. +      if (base.x < scroll_x + int2fp(screen->w/2 - 10))
  299.  #ifndef GP2X
  300.          play_sound(sounds[SND_EXPLODE], SOUND_LEFT_SPEAKER);
  301. -      else if (base.x > scroll_x + screen->w/2 + 10)
  302. +      else if (base.x > scroll_x + int2fp(screen->w/2 + 10))
  303.          play_sound(sounds[SND_EXPLODE], SOUND_RIGHT_SPEAKER);
  304.        else
  305.          play_sound(sounds[SND_EXPLODE], SOUND_CENTER_SPEAKER);
  306. @@ -481,12 +484,12 @@
  307.    }
  308.  
  309.    // move
  310. -  physic.apply(frame_ratio, base.x, base.y);                
  311. +  physic.apply(frame_ratio, base.x, base.y);
  312.    collision_swept_object_map(&old_base,&base);
  313.  }
  314.  
  315.  void
  316. -BadGuy::action_stalactite(double frame_ratio)
  317. +BadGuy::action_stalactite(fp frame_ratio)
  318.  {
  319.    Player& tux = *World::current()->get_tux();
  320.  
  321. @@ -496,20 +499,20 @@
  322.    if(mode == NORMAL) {
  323.      // start shaking when tux is below the stalactite and at least 40 pixels
  324.      // near
  325. -    if(tux.base.x + 32 > base.x - RANGE && tux.base.x < base.x + 32 + RANGE
  326. +    if(tux.base.x + int2fp(32) > base.x - int2fp(RANGE) && tux.base.x < base.x + int2fp(32) + int2fp(RANGE)
  327.              && tux.base.y + tux.base.height > base.y) {
  328.        timer.start(SHAKETIME);
  329.        mode = STALACTITE_SHAKING;
  330.      }
  331.    } if(mode == STALACTITE_SHAKING) {
  332. -    base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer...
  333. +    base.x = old_base.x + int2fp((rand() % 6) - 3); // TODO this could be done nicer...
  334.      if(!timer.check()) {
  335.        mode = STALACTITE_FALL;
  336.      }
  337.    } else if(mode == STALACTITE_FALL) {
  338.      fall();
  339.      /* Destroy if we collides with land */
  340. -    if(issolid(base.x+base.width/2, base.y+base.height))
  341. +    if(issolid(fp2int(base.x+base.width/2), fp2int(base.y+base.height)))
  342.      {
  343.        timer.start(2000);
  344.        dying = DYING_SQUISHED;
  345. @@ -528,24 +531,21 @@
  346.  }
  347.  
  348.  void
  349. -BadGuy::action_flame(double frame_ratio)
  350. +BadGuy::action_flame(fp frame_ratio)
  351.  {
  352. -    static const float radius = 100;
  353. -    static const float speed = 0.02;
  354. -    base.x = old_base.x + cos(base.ym) * radius;
  355. -    base.y = old_base.y + sin(base.ym) * radius;
  356. +    base.x = old_base.x + fpcos(base.ym * 256 / (2*FP_PI)) * FLAME_RADIUS;
  357. +    base.y = old_base.y + fpsin(base.ym * 256 / (2*FP_PI)) * FLAME_RADIUS;
  358.  
  359. -    base.ym = fmodf(base.ym + frame_ratio * speed, 2*M_PI);
  360. +    base.ym = (base.ym + fpmul(frame_ratio, FP_FLAME_SPEED)) % (2*FP_PI);
  361.  }
  362.  
  363.  void
  364. -BadGuy::action_fish(double frame_ratio)
  365. +BadGuy::action_fish(fp frame_ratio)
  366.  {
  367. -  static const float JUMPV = 6;
  368.    static const int WAITTIME = 1000;
  369.      
  370.    // go in wait mode when back in water
  371. -  if(dying == DYING_NOT && gettile(base.x, base.y+ base.height)->water
  372. +  if(dying == DYING_NOT && gettile(fp2int(base.x), fp2int(base.y+ base.height))->water
  373.          && physic.get_velocity_y() <= 0 && mode == NORMAL)
  374.      {
  375.        mode = FISH_WAIT;
  376. @@ -559,7 +559,7 @@
  377.        // jump again
  378.        set_sprite(img_fish, img_fish);
  379.        mode = NORMAL;
  380. -      physic.set_velocity(0, JUMPV);
  381. +      physic.set_velocity(0, FP_JUMP_SPEED);
  382.        physic.enable_gravity(true);
  383.      }
  384.  
  385. @@ -572,16 +572,14 @@
  386.  }
  387.  
  388.  void
  389. -BadGuy::action_bouncingsnowball(double frame_ratio)
  390. +BadGuy::action_bouncingsnowball(fp frame_ratio)
  391.  {
  392. -  static const float JUMPV = 4.5;
  393. -    
  394.    fall();
  395.  
  396.    // jump when on ground
  397. -  if(dying == DYING_NOT && issolid(base.x, base.y+32))
  398. +  if(dying == DYING_NOT && issolid(fp2int(base.x), fp2int(base.y)+32))
  399.      {
  400. -      physic.set_velocity_y(JUMPV);
  401. +      physic.set_velocity_y(FP_SNOWBALL_JUMP_SPEED);
  402.        physic.enable_gravity(true);
  403.      }                                                    
  404.    else
  405. @@ -606,25 +604,24 @@
  406.  }
  407.  
  408.  void
  409. -BadGuy::action_flyingsnowball(double frame_ratio)
  410. +BadGuy::action_flyingsnowball(fp frame_ratio)
  411.  {
  412. -  static const float FLYINGSPEED = 1;
  413.    static const int DIRCHANGETIME = 1000;
  414.      
  415.    // go into flyup mode if none specified yet
  416.    if(dying == DYING_NOT && mode == NORMAL) {
  417.      mode = FLY_UP;
  418. -    physic.set_velocity_y(FLYINGSPEED);
  419. +    physic.set_velocity_y(FP_FLYING_SPEED);
  420.      timer.start(DIRCHANGETIME/2);
  421.    }
  422.  
  423.    if(dying == DYING_NOT && !timer.check()) {
  424.      if(mode == FLY_UP) {
  425.        mode = FLY_DOWN;
  426. -      physic.set_velocity_y(-FLYINGSPEED);
  427. +      physic.set_velocity_y(-FP_FLYING_SPEED);
  428.      } else if(mode == FLY_DOWN) {
  429.        mode = FLY_UP;
  430. -      physic.set_velocity_y(FLYINGSPEED);
  431. +      physic.set_velocity_y(FP_FLYING_SPEED);
  432.      }
  433.      timer.start(DIRCHANGETIME);
  434.    }
  435. @@ -646,7 +643,7 @@
  436.  }
  437.  
  438.  void
  439. -BadGuy::action_spiky(double frame_ratio)
  440. +BadGuy::action_spiky(fp frame_ratio)
  441.  {
  442.    if (dying == DYING_NOT)
  443.      check_horizontal_bump();
  444. @@ -655,9 +652,9 @@
  445.  #if 0
  446.    // jump when we're about to fall
  447.    if (physic.get_velocity_y() == 0 &&
  448. -          !issolid(base.x+base.width/2, base.y + base.height)) {
  449. +          !issolid(fp2int(base.x+base.width/2), fp2int(base.y + base.height))) {
  450.      physic.enable_gravity(true);
  451. -    physic.set_velocity_y(2);
  452. +    physic.set_velocity_y(FP_SPIKY_JUMP_SPEED);
  453.    }
  454.  #endif
  455.  
  456. @@ -667,7 +664,7 @@
  457.  }
  458.  
  459.  void
  460. -BadGuy::action_snowball(double frame_ratio)
  461. +BadGuy::action_snowball(fp frame_ratio)
  462.  {
  463.    if (dying == DYING_NOT)
  464.      check_horizontal_bump();
  465. @@ -680,10 +677,10 @@
  466.  }
  467.  
  468.  void
  469. -BadGuy::action(double frame_ratio)
  470. +BadGuy::action(fp frame_ratio)
  471.  {
  472.    // Remove if it's far off the screen:
  473. -  if (base.x < scroll_x - OFFSCREEN_DISTANCE)
  474. +  if (base.x < scroll_x - int2fp(OFFSCREEN_DISTANCE))
  475.      {
  476.        remove_me();                                                
  477.        return;
  478. @@ -691,9 +688,9 @@
  479.  
  480.    // BadGuy fall below the ground
  481.  #ifndef RES320X240
  482. -  if (base.y > screen->h) {
  483. +  if (base.y > int2fp(screen->h)) {
  484.  #else
  485. -  if (base.y > 640) {
  486. +    if (base.y > int2fp(640)) {
  487.  #endif
  488.      remove_me();
  489.      return;
  490. @@ -701,9 +698,9 @@
  491.  
  492.    // Once it's on screen, it's activated!
  493.  #ifndef RES320X240
  494. -  if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
  495. +  if (base.x <= scroll_x + int2fp(screen->w + OFFSCREEN_DISTANCE))
  496.  #else
  497. -  if (base.x <= scroll_x + 640 + OFFSCREEN_DISTANCE)
  498. +    if (base.x <= scroll_x + int2fp(640 + OFFSCREEN_DISTANCE))
  499.  #endif
  500.      seen = true;
  501.  
  502. @@ -765,9 +762,9 @@
  503.  {
  504.    // Don't try to draw stuff that is outside of the screen
  505.  #ifndef RES320X240
  506. -  if(base.x <= scroll_x - base.width || base.x >= scroll_x + screen->w)
  507. +  if(base.x <= scroll_x - base.width || base.x >= scroll_x + int2fp(screen->w))
  508.  #else
  509. -  if(base.x <= scroll_x - base.width || base.x >= scroll_x + 640)
  510. +  if(base.x <= scroll_x - base.width || base.x >= scroll_x + int2fp(640))
  511.  #endif
  512.      return;
  513.    
  514. @@ -777,10 +774,10 @@
  515.      }
  516.  
  517.    Sprite* sprite = (dir == LEFT) ? sprite_left : sprite_right;
  518. -  sprite->draw(base.x - scroll_x, base.y);
  519. +  sprite->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  520.  
  521.    if (debug_mode)
  522. -    fillrect(base.x - scroll_x, base.y, base.width, base.height, 75,0,75, 150);
  523. +    fillrect(fp2int(base.x - scroll_x), fp2int(base.y), fp2int(base.width), fp2int(base.height), 75,0,75, 150);
  524.  }
  525.  
  526.  void
  527. @@ -788,8 +785,8 @@
  528.  {
  529.    if (1)
  530.      {
  531. -      base.width = 32;
  532. -      base.height = 32;
  533. +      base.width = int2fp(32);
  534. +      base.height = int2fp(32);
  535.      }
  536.    else
  537.      {
  538. @@ -798,13 +795,13 @@
  539.        // representation
  540.        if(left != 0) {
  541.          if(base.width == 0 && base.height == 0) {
  542. -          base.width  = left->get_width();
  543. -          base.height = left->get_height();
  544. -        } else if(base.width != left->get_width() || base.height != left->get_height()) {
  545. -          base.x -= (left->get_width() - base.width) / 2;
  546. -          base.y -= left->get_height() - base.height;
  547. -          base.width = left->get_width();
  548. -          base.height = left->get_height();
  549. +          base.width  = int2fp(left->get_width());
  550. +          base.height = int2fp(left->get_height());
  551. +        } else if(base.width != int2fp(left->get_width()) || base.height != int2fp(left->get_height())) {
  552. +          base.x -= (int2fp(left->get_width()) - base.width) / 2;
  553. +          base.y -= int2fp(left->get_height()) - base.height;
  554. +          base.width = int2fp(left->get_width());
  555. +          base.height = int2fp(left->get_height());
  556.            old_base = base;
  557.          }
  558.        } else {
  559. @@ -825,7 +822,7 @@
  560.        || kind == BAD_FLYINGSNOWBALL)
  561.      return;
  562.  
  563. -  physic.set_velocity_y(3);
  564. +  physic.set_velocity_y(FP_BUMP_SPEED);
  565.    kill_me(25);
  566.  }
  567.  
  568. @@ -891,10 +888,10 @@
  569.  #endif
  570.  
  571.          if (player->base.x < base.x + (base.width/2)) {
  572. -          physic.set_velocity_x(5);
  573. +          physic.set_velocity_x(FP_MRICEBLOCK_SPEED_2);
  574.            dir = RIGHT;
  575.          } else {
  576. -          physic.set_velocity_x(-5);
  577. +          physic.set_velocity_x(-FP_MRICEBLOCK_SPEED_2);
  578.            dir = LEFT;
  579.          }
  580.  
  581. @@ -1060,12 +1057,12 @@
  582.            if (pbad_c->dir == LEFT)
  583.            {
  584.              dir = RIGHT;
  585. -            physic.set_velocity(fabsf(physic.get_velocity_x()), 2);
  586. +            physic.set_velocity(abs(physic.get_velocity_x()), FP_BOUNCE_SPEED);
  587.            }
  588.            else if (pbad_c->dir == RIGHT)
  589.            {
  590.              dir = LEFT;
  591. -            physic.set_velocity(-fabsf(physic.get_velocity_x()), 2);
  592. +            physic.set_velocity(-abs(physic.get_velocity_x()), FP_BOUNCE_SPEED);
  593.            }
  594.  
  595.  
  596. @@ -1080,12 +1077,12 @@
  597.              if (dir == LEFT)
  598.              {
  599.                dir = RIGHT;
  600. -              physic.set_velocity_x(fabsf(physic.get_velocity_x()));
  601. +              physic.set_velocity_x(abs(physic.get_velocity_x()));
  602.              }
  603.              else if (dir == RIGHT)
  604.              {
  605.                dir = LEFT;
  606. -              physic.set_velocity_x(-fabsf(physic.get_velocity_x()));
  607. +              physic.set_velocity_x(-abs(physic.get_velocity_x()));
  608.              }
  609.  
  610.            }
  611. @@ -1106,12 +1103,12 @@
  612.  
  613.          // Hit from left side
  614.          if (player->base.x < base.x) {
  615. -          physic.set_velocity_x(5);
  616. +          physic.set_velocity_x(FP_MRICEBLOCK_SPEED_2);
  617.            dir = RIGHT;
  618.          }
  619.          // Hit from right side
  620.          else {
  621. -          physic.set_velocity_x(-5);
  622. +          physic.set_velocity_x(-FP_MRICEBLOCK_SPEED_2);
  623.            dir = LEFT;
  624.          }
  625.  
  626. diff -Naur supertux-0.1.3/src.bak/badguy.h supertux-0.1.3/src/badguy.h
  627. --- supertux-0.1.3/src.bak/badguy.h 2014-12-06 18:00:56.000000000 -0500
  628. +++ supertux-0.1.3/src/badguy.h 2014-12-06 18:03:09.000000000 -0500
  629. @@ -105,9 +105,9 @@
  630.    int animation_offset;
  631.  
  632.  public:
  633. -  BadGuy(float x, float y, BadGuyKind kind, bool stay_on_platform);
  634. +  BadGuy(fp x, fp y, BadGuyKind kind, bool stay_on_platform);
  635.  
  636. -  void action(double frame_ratio);
  637. +  void action(fp frame_ratio);
  638.    void draw();
  639.    std::string type() { return "BadGuy"; };
  640.  
  641. @@ -129,17 +129,17 @@
  642.    bool is_removable() const { return removable; }
  643.  
  644.  private:
  645. -  void action_mriceblock(double frame_ratio);
  646. -  void action_jumpy(double frame_ratio);
  647. -  void action_bomb(double frame_ratio);
  648. -  void action_mrbomb(double frame_ratio);
  649. -  void action_stalactite(double frame_ratio);
  650. -  void action_flame(double frame_ratio);
  651. -  void action_fish(double frame_ratio);
  652. -  void action_bouncingsnowball(double frame_ratio);
  653. -  void action_flyingsnowball(double frame_ratio);
  654. -  void action_spiky(double frame_ratio);
  655. -  void action_snowball(double frame_ratio);
  656. +  void action_mriceblock(fp frame_ratio);
  657. +  void action_jumpy(fp frame_ratio);
  658. +  void action_bomb(fp frame_ratio);
  659. +  void action_mrbomb(fp frame_ratio);
  660. +  void action_stalactite(fp frame_ratio);
  661. +  void action_flame(fp frame_ratio);
  662. +  void action_fish(fp frame_ratio);
  663. +  void action_bouncingsnowball(fp frame_ratio);
  664. +  void action_flyingsnowball(fp frame_ratio);
  665. +  void action_spiky(fp frame_ratio);
  666. +  void action_snowball(fp frame_ratio);
  667.  
  668.    /** handles falling down. disables gravity calculation when we're back on
  669.     * ground */
  670. @@ -169,7 +169,7 @@
  671.    int y;
  672.    bool stay_on_platform;
  673.  
  674. -  BadGuyData(BadGuy* pbadguy) : kind(pbadguy->kind), x((int)pbadguy->base.x), y((int)pbadguy->base.y), stay_on_platform(pbadguy->stay_on_platform)  {};
  675. +  BadGuyData(BadGuy* pbadguy) : kind(pbadguy->kind), x(fp2int(pbadguy->base.x)), y(fp2int(pbadguy->base.y)), stay_on_platform(pbadguy->stay_on_platform)  {};
  676.    BadGuyData(BadGuyKind kind_, int x_, int y_, bool stay_on_platform_)
  677.      : kind(kind_), x(x_), y(y_), stay_on_platform(stay_on_platform_) {}
  678.  
  679. diff -Naur supertux-0.1.3/src.bak/collision.cpp supertux-0.1.3/src/collision.cpp
  680. --- supertux-0.1.3/src.bak/collision.cpp    2014-12-06 18:00:56.000000000 -0500
  681. +++ supertux-0.1.3/src/collision.cpp    2014-12-06 18:03:09.000000000 -0500
  682. @@ -25,21 +25,22 @@
  683.  #include "world.h"
  684.  #include "level.h"
  685.  #include "tile.h"
  686. +#include "fpmath.h"
  687.  
  688.  bool rectcollision(const base_type& one, const base_type& two)
  689.  {
  690. -  return (one.x >= two.x - one.width + 1  &&
  691. -          one.x <= two.x + two.width - 1  &&
  692. -          one.y >= two.y - one.height + 1 &&
  693. -          one.y <= two.y + two.height - 1);
  694. +  return (one.x >= two.x - one.width + int2fp(1)  &&
  695. +          one.x <= two.x + two.width - int2fp(1)  &&
  696. +          one.y >= two.y - one.height + int2fp(1) &&
  697. +          one.y <= two.y + two.height - int2fp(1));
  698.  }
  699.  
  700. -bool rectcollision_offset(const base_type& one, const base_type& two, float off_x, float off_y)
  701. -{
  702. -  return (one.x >= two.x - one.width  + off_x + 1 &&
  703. -          one.x <= two.x + two.width  + off_x - 1 &&
  704. -          one.y >= two.y - one.height + off_y + 1 &&
  705. -          one.y <= two.y + two.height + off_y - 1);
  706. +bool rectcollision_offset(const base_type& one, const base_type& two, fp off_x, fp off_y)
  707. +{
  708. +  return (one.x >= two.x - one.width  + off_x + int2fp(1) &&
  709. +          one.x <= two.x + two.width  + off_x - int2fp(1) &&
  710. +          one.y >= two.y - one.height + off_y + int2fp(1) &&
  711. +          one.y <= two.y + two.height + off_y - int2fp(1));
  712.  }
  713.  
  714.  bool collision_object_map(const base_type& base)
  715. @@ -51,10 +52,10 @@
  716.    TileManager& tilemanager = *TileManager::instance();
  717.  
  718.    // we make the collision rectangle 1 pixel smaller
  719. -  int starttilex = int(base.x+1) / 32;
  720. -  int starttiley = int(base.y+1) / 32;
  721. -  int max_x = int(base.x + base.width);
  722. -  int max_y = int(base.y + base.height);
  723. +  int starttilex = (fp2int(base.x)+1) / 32;
  724. +  int starttiley = (fp2int(base.y)+1) / 32;
  725. +  int max_x = fp2int(base.x + base.width);
  726. +  int max_y = fp2int(base.y + base.height);
  727.  
  728.    for(int x = starttilex; x*32 < max_x; ++x) {
  729.      for(int y = starttiley; y*32 < max_y; ++y) {
  730. @@ -72,10 +73,10 @@
  731.    const Level& level = *World::current()->get_level();
  732.    TileManager& tilemanager = *TileManager::instance();
  733.    
  734. -  int starttilex = int(base.x) / 32;
  735. -  int starttiley = int(base.y) / 32;
  736. -  int max_x = int(base.x + base.width);
  737. -  int max_y = int(base.y + base.height);
  738. +  int starttilex = fp2int(base.x) / 32;
  739. +  int starttiley = fp2int(base.y) / 32;
  740. +  int max_x = fp2int(base.x + base.width);
  741. +  int max_y = fp2int(base.y + base.height);
  742.  
  743.    for(int x = starttilex; x*32 < max_x; ++x) {
  744.      for(int y = starttiley; y*32 < max_y; ++y) {
  745. @@ -105,9 +106,9 @@
  746.  {
  747.    int steps; /* Used to speed up the collision tests, by stepping every 16pixels in the path. */
  748.    int h;
  749. -  float lpath; /* Holds the longest path, which is either in X or Y direction. */
  750. -  float xd,yd; /* Hold the smallest steps in X and Y directions. */
  751. -  float temp, xt, yt; /* Temporary variable. */
  752. +  fp lpath; /* Holds the longest path, which is either in X or Y direction. */
  753. +  fp xd,yd; /* Hold the smallest steps in X and Y directions. */
  754. +  fp temp, xt, yt; /* Temporary variable. */
  755.  
  756.    lpath = 0;
  757.    xd = 0;
  758. @@ -122,12 +123,12 @@
  759.        lpath = current->y - old->y;
  760.        if(lpath < 0)
  761.          {
  762. -          yd = -1;
  763. +          yd = int2fp(-1);
  764.            lpath = -lpath;
  765.          }
  766.        else
  767.          {
  768. -          yd = 1;
  769. +          yd = int2fp(1);
  770.          }
  771.  
  772.        h = 1;
  773. @@ -138,12 +139,12 @@
  774.        lpath = current->x - old->x;
  775.        if(lpath < 0)
  776.          {
  777. -          xd = -1;
  778. +          xd = int2fp(-1);
  779.            lpath = -lpath;
  780.          }
  781.        else
  782.          {
  783. -          xd = 1;
  784. +          xd = int2fp(1);
  785.          }
  786.        h = 2;
  787.        yd = 0;
  788. @@ -158,23 +159,23 @@
  789.        if(lpath < 0)
  790.          lpath = -lpath;
  791.        h = 3;
  792. -      xd = (current->x - old->x) / lpath;
  793. -      yd = (current->y - old->y) / lpath;
  794. +      xd = fpdiv((current->x - old->x), lpath);
  795. +      yd = fpdiv((current->y - old->y), lpath);
  796.      }
  797.  
  798. -  steps = (int)(lpath / (float)16);
  799. +  steps = fp2int(lpath / 16);
  800.  
  801. -  float orig_x = old->x;
  802. -  float orig_y = old->y;
  803. +  fp orig_x = old->x;
  804. +  fp orig_y = old->y;
  805.    old->x += xd;
  806.    old->y += yd;
  807.  
  808. -  for(float i = 0; i <= lpath; old->x += xd, old->y += yd, ++i)
  809. +  for(fp i = 0; i <= lpath; old->x += xd, old->y += yd, i += int2fp(1))
  810.      {
  811.        if(steps > 0)
  812.          {
  813. -          old->y += yd*16.;
  814. -          old->x += xd*16.;
  815. +          old->y += yd*16;
  816. +          old->x += xd*16;
  817.            steps--;
  818.          }
  819.  
  820. @@ -240,36 +241,36 @@
  821.    *old = *current;
  822.  }
  823.  
  824. -Tile* gettile(float x, float y)
  825. +Tile* gettile(int x, int y)
  826.  {
  827.    return TileManager::instance()->get(World::current()->get_level()->gettileid(x, y));
  828.  }
  829.  
  830. -bool issolid(float x, float y)
  831. +bool issolid(int x, int y)
  832.  {
  833.    Tile* tile = gettile(x,y);
  834.    return tile && tile->solid;
  835.  }
  836.  
  837. -bool isbrick(float x, float y)
  838. +bool isbrick(int x, int y)
  839.  {
  840.    Tile* tile = gettile(x,y);
  841.    return tile && tile->brick;
  842.  }
  843.  
  844. -bool isice(float x, float y)
  845. +bool isice(int x, int y)
  846.  {
  847.    Tile* tile = gettile(x,y);
  848.    return tile && tile->ice;
  849.  }
  850.  
  851. -bool isfullbox(float x, float y)
  852. +bool isfullbox(int x, int y)
  853.  {
  854.    Tile* tile = gettile(x,y);
  855.    return tile && tile->fullbox;
  856.  }
  857.  
  858. -bool isdistro(float x, float y)
  859. +bool isdistro(int x, int y)
  860.  {
  861.    Tile* tile = gettile(x,y);
  862.    return tile && tile->distro;
  863. diff -Naur supertux-0.1.3/src.bak/collision.h supertux-0.1.3/src/collision.h
  864. --- supertux-0.1.3/src.bak/collision.h  2014-12-06 18:00:56.000000000 -0500
  865. +++ supertux-0.1.3/src/collision.h  2014-12-06 18:03:09.000000000 -0500
  866. @@ -41,19 +41,19 @@
  867.  };
  868.  
  869.  bool rectcollision(const base_type& one, const base_type& two);
  870. -bool rectcollision_offset(const base_type& one, const base_type& two, float off_x, float off_y);
  871. +bool rectcollision_offset(const base_type& one, const base_type& two, fp off_x, fp off_y);
  872.  
  873.  void collision_swept_object_map(base_type* old, base_type* current);
  874.  bool collision_object_map(const base_type& object);
  875.  
  876.  /** Return a pointer to the tile at the given x/y coordinates */
  877. -Tile* gettile(float x, float y);
  878. +Tile* gettile(int x, int y);
  879.  
  880.  // Some little helper function to check for tile properties
  881. -bool  issolid(float x, float y);
  882. -bool  isbrick(float x, float y);
  883. -bool  isice(float x, float y);
  884. -bool  isfullbox(float x, float y);
  885. +bool  issolid(int x, int y);
  886. +bool  isbrick(int x, int y);
  887. +bool  isice(int x, int y);
  888. +bool  isfullbox(int x, int y);
  889.  
  890.  typedef void* (*tiletestfunction)(Tile* tile);
  891.  /** invokes the function for each tile the baserectangle collides with. The
  892. diff -Naur supertux-0.1.3/src.bak/configfile.cpp supertux-0.1.3/src/configfile.cpp
  893. --- supertux-0.1.3/src.bak/configfile.cpp   2014-12-06 18:00:56.000000000 -0500
  894. +++ supertux-0.1.3/src/configfile.cpp   2014-12-06 18:06:14.000000000 -0500
  895. @@ -37,7 +37,7 @@
  896.    debug_mode = false;
  897.    audio_device = true;
  898.  
  899. -  use_fullscreen = true;
  900. +  use_fullscreen = false;
  901.    show_fps = false;
  902.    use_gl = false;
  903.  
  904. diff -Naur supertux-0.1.3/src.bak/defines.h supertux-0.1.3/src/defines.h
  905. --- supertux-0.1.3/src.bak/defines.h    2014-12-06 18:00:56.000000000 -0500
  906. +++ supertux-0.1.3/src/defines.h    2014-12-07 10:59:26.000000000 -0500
  907. @@ -55,30 +55,76 @@
  908.  
  909.  /* Speed constraints: */
  910.  
  911. -#define MAX_WALK_XM 2.3
  912. -#define MAX_RUN_XM 3.2
  913. -#define MAX_YM 20.0
  914. +#define FP_MAX_WALK_XM 37683              /* 2.3 */
  915. +#define FP_MAX_RUN_XM 52428               /* 3.2 */
  916. +//#define MAX_YM 20.0
  917.  #define MAX_JUMP_TIME 375
  918.  #define MAX_LIVES 99
  919.  
  920. -#define WALK_SPEED 1.0
  921. -#define RUN_SPEED 1.5
  922. -#define JUMP_SPEED 1.2
  923. +#define WALK_SPEED 1
  924. +#define FP_WALK_SPEED 16384               /* 1.0 */
  925. +//#define RUN_SPEED 1.5
  926. +//#define JUMP_SPEED 1.2
  927. +
  928. +#define FP_BADGUY_WALK_SPEED 13107        /* 0.8 */
  929. +#define FP_BOUNCINGSNOWBALL_SPEED 21299   /* 1.3 */
  930. +#define FP_MRICEBLOCK_SPEED 57344         /* 3.5 */
  931. +#define FP_MRICEBLOCK_SPEED_2 81920       /* 5.0 */
  932. +
  933. +#define FP_WALK_JUMP_SPEED 85196          /* 5.2 */
  934. +#define FP_RUN_JUMP_SPEED 95027           /* 5.8 */
  935. +#define FP_KILL_SPEED 114688              /* 7.0 */
  936. +
  937. +#define FP_JUMP_SPEED 98304               /* 6.0 */
  938. +#define FP_JUMP_SPEED_START 91750         /* 5.6 */
  939. +#define FP_JUMP_SPEED_MIDDLE 86835        /* 5.3 */
  940. +#define FP_BOUNCE_SPEED 32768             /* 2.0 */
  941. +
  942. +#define FP_SNOWBALL_JUMP_SPEED 73728      /* 4.5 */
  943. +#define FP_FLYING_SPEED 16384             /* 1.0 */
  944. +#define FP_SPIKY_JUMP_SPEED 32768         /* 2.0 */
  945. +#define FP_BUMP_SPEED 49152               /* 3.0 */
  946. +
  947. +#define FP_UPGRADE_SPEED_X 16384          /* 1.0 */
  948. +#define FP_UPGRADE_SPEED_Y 65536          /* 4.0 */
  949. +#define FP_GROWUP_SPEED 16384             /* 1.0 */
  950. +
  951. +#define FP_BOUNCY_BRICK_MAX_OFFSET 131072 /* 8.0 */
  952. +#define FP_BOUNCY_BRICK_SPEED 14745       /* 0.9 */
  953. +
  954. +#define FP_BULLET_STARTING_YM 0           /* 0.0 */
  955. +#define FP_BULLET_XM 98304                /* 6.0 */
  956. +
  957. +#define FP_RISE_RATIO 11468               /* 0.7 */
  958. +
  959. +#define FLAME_RADIUS 100
  960. +#define FP_FLAME_SPEED 327                /* 0.02 */
  961. +
  962. +#define FP_MIN_PARTICLE_SPEED 163         /* 0.01 */
  963. +
  964. +#define FP_BROKEN_PIECE_SPEED 24576       /* 1.5 */
  965.  
  966.  /* gameplay related defines */
  967.  
  968. +#define FP_PI 51471                       /* 3.14159265 */
  969. +
  970.  #define START_LIVES 4
  971.  
  972.  #define MAX_BULLETS 2
  973.  
  974. -#define YM_FOR_JUMP 6.0
  975. -#define WALK_ACCELERATION_X 0.03
  976. -#define RUN_ACCELERATION_X 0.04
  977. -#define KILL_BOUNCE_YM 8.0
  978. +//#define YM_FOR_JUMP 6.0
  979. +#define FP_WALK_ACCELERATION_X 491        /* 0.03 */
  980. +#define FP_RUN_ACCELERATION_X 655         /* 0.04 */
  981. +//#define KILL_BOUNCE_YM 8.0
  982.  
  983. -#define SKID_XM 2.0
  984. +#define FP_SKID_XM 32768                  /* 2.0 */
  985.  #define SKID_TIME 200
  986.  
  987. +#define FP_FRAME_RATIO_LIMIT 24576        /* 1.5 */
  988. +#define FP_FRAME_RATIO_CORR 13926         /* 0.85 */
  989. +
  990. +#define FP_MENU_RATIO 8192                /* 0.5 */
  991. +
  992.  /* Size constraints: */
  993.  
  994.  #define OFFSCREEN_DISTANCE 256
  995. @@ -92,11 +138,12 @@
  996.  /* Scrolling text speed */
  997.  
  998.  #ifndef RES320X240
  999. -#define SCROLL_SPEED_CREDITS 1.2
  1000. +#define FP_SCROLL_SPEED_CREDITS 19660         /* 1.2 */
  1001.  #else
  1002. -#define SCROLL_SPEED_CREDITS 2.4
  1003. +#define FP_SCROLL_SPEED_CREDITS 39321            /* 2.4 */
  1004.  #endif
  1005. -#define SCROLL_SPEED_MESSAGE 1.0
  1006. +#define FP_SCROLL_SPEED_MESSAGE 16384         /* 1.0 */
  1007. +#define FP_SPEED_INC 163                   /* 0.01 */
  1008.  
  1009.  /* Debugging */
  1010.  
  1011. diff -Naur supertux-0.1.3/src.bak/fpmath.cpp supertux-0.1.3/src/fpmath.cpp
  1012. --- supertux-0.1.3/src.bak/fpmath.cpp   1969-12-31 19:00:00.000000000 -0500
  1013. +++ supertux-0.1.3/src/fpmath.cpp   2014-12-06 18:04:18.000000000 -0500
  1014. @@ -0,0 +1,87 @@
  1015. +//  $Id: fpmath.cpp,v Exp $
  1016. +//
  1017. +//  SuperTux -  A Jump'n Run
  1018. +//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
  1019. +//
  1020. +//  This program is free software; you can redistribute it and/or
  1021. +//  modify it under the terms of the GNU General Public License
  1022. +//  as published by the Free Software Foundation; either version 2
  1023. +//  of the License, or (at your option) any later version.
  1024. +//
  1025. +//  This program is distributed in the hope that it will be useful,
  1026. +//  but WITHOUT ANY WARRANTY; without even the implied warranty of
  1027. +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1028. +//  GNU General Public License for more details.
  1029. +//
  1030. +//  You should have received a copy of the GNU General Public License
  1031. +//  along with this program; if not, write to the Free Software
  1032. +//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  1033. +
  1034. +#include "fpmath.h"
  1035. +
  1036. +// Fixed point sine and cosine tables, based
  1037. +// on 256 'degrees' in a circle.
  1038. +
  1039. +fp sine[] = {
  1040. +0, 402, 804, 1205, 1606, 2006, 2404, 2801, 3196,
  1041. +3590, 3981, 4370, 4756, 5139, 5520, 5897, 6270, 6639,
  1042. +7005, 7366, 7723, 8076, 8423, 8765, 9102, 9434, 9760,
  1043. +10080, 10394, 10702, 11003, 11297, 11585, 11866, 12140, 12406,
  1044. +12665, 12916, 13160, 13395, 13623, 13842, 14053, 14256, 14449,
  1045. +14635, 14811, 14978, 15137, 15286, 15426, 15557, 15679, 15791,
  1046. +15893, 15986, 16069, 16143, 16207, 16261, 16305, 16340, 16364,
  1047. +16379, 16384, 16379, 16364, 16340, 16305, 16261, 16207, 16143,
  1048. +16069, 15986, 15893, 15791, 15679, 15557, 15426, 15286, 15137,
  1049. +14978, 14811, 14635, 14449, 14256, 14053, 13842, 13623, 13395,
  1050. +13160, 12916, 12665, 12406, 12140, 11866, 11585, 11297, 11003,
  1051. +10702, 10394, 10080, 9760, 9434, 9102, 8765, 8423, 8076,
  1052. +7723, 7366, 7005, 6639, 6270, 5897, 5520, 5139, 4756,
  1053. +4370, 3981, 3590, 3196, 2801, 2404, 2006, 1606, 1205,
  1054. +804, 402, 0, -402, -804, -1205, -1606, -2006, -2404,
  1055. +-2801, -3196, -3590, -3981, -4370, -4756, -5139, -5520, -5897,
  1056. +-6270, -6639, -7005, -7366, -7723, -8076, -8423, -8765, -9102,
  1057. +-9434, -9760, -10080, -10394, -10702, -11003, -11297, -11585, -11866,
  1058. +-12140, -12406, -12665, -12916, -13160, -13395, -13623, -13842, -14053,
  1059. +-14256, -14449, -14635, -14811, -14978, -15137, -15286, -15426, -15557,
  1060. +-15679, -15791, -15893, -15986, -16069, -16143, -16207, -16261, -16305,
  1061. +-16340, -16364, -16379, -16384, -16379, -16364, -16340, -16305, -16261,
  1062. +-16207, -16143, -16069, -15986, -15893, -15791, -15679, -15557, -15426,
  1063. +-15286, -15137, -14978, -14811, -14635, -14449, -14256, -14053, -13842,
  1064. +-13623, -13395, -13160, -12916, -12665, -12406, -12140, -11866, -11585,
  1065. +-11297, -11003, -10702, -10394, -10080, -9760, -9434, -9102, -8765,
  1066. +-8423, -8076, -7723, -7366, -7005, -6639, -6270, -5897, -5520,
  1067. +-5139, -4756, -4370, -3981, -3590, -3196, -2801, -2404, -2006,
  1068. +-1606, -1205, -804, -402
  1069. +};
  1070. +
  1071. +fp cosine[] = {
  1072. +16384, 16379, 16364, 16340, 16305, 16261, 16207, 16143, 16069,
  1073. +15986, 15893, 15791, 15679, 15557, 15426, 15286, 15137, 14978,
  1074. +14811, 14635, 14449, 14256, 14053, 13842, 13623, 13395, 13160,
  1075. +12916, 12665, 12406, 12140, 11866, 11585, 11297, 11003, 10702,
  1076. +10394, 10080, 9760, 9434, 9102, 8765, 8423, 8076, 7723,
  1077. +7366, 7005, 6639, 6270, 5897, 5520, 5139, 4756, 4370,
  1078. +3981, 3590, 3196, 2801, 2404, 2006, 1606, 1205, 804,
  1079. +402, 0, -402, -804, -1205, -1606, -2006, -2404, -2801,
  1080. +-3196, -3590, -3981, -4370, -4756, -5139, -5520, -5897, -6270,
  1081. +-6639, -7005, -7366, -7723, -8076, -8423, -8765, -9102, -9434,
  1082. +-9760, -10080, -10394, -10702, -11003, -11297, -11585, -11866, -12140,
  1083. +-12406, -12665, -12916, -13160, -13395, -13623, -13842, -14053, -14256,
  1084. +-14449, -14635, -14811, -14978, -15137, -15286, -15426, -15557, -15679,
  1085. +-15791, -15893, -15986, -16069, -16143, -16207, -16261, -16305, -16340,
  1086. +-16364, -16379, -16384, -16379, -16364, -16340, -16305, -16261, -16207,
  1087. +-16143, -16069, -15986, -15893, -15791, -15679, -15557, -15426, -15286,
  1088. +-15137, -14978, -14811, -14635, -14449, -14256, -14053, -13842, -13623,
  1089. +-13395, -13160, -12916, -12665, -12406, -12140, -11866, -11585, -11297,
  1090. +-11003, -10702, -10394, -10080, -9760, -9434, -9102, -8765, -8423,
  1091. +-8076, -7723, -7366, -7005, -6639, -6270, -5897, -5520, -5139,
  1092. +-4756, -4370, -3981, -3590, -3196, -2801, -2404, -2006, -1606,
  1093. +-1205, -804, -402, 0, 402, 804, 1205, 1606, 2006,
  1094. +2404, 2801, 3196, 3590, 3981, 4370, 4756, 5139, 5520,
  1095. +5897, 6270, 6639, 7005, 7366, 7723, 8076, 8423, 8765,
  1096. +9102, 9434, 9760, 10080, 10394, 10702, 11003, 11297, 11585,
  1097. +11866, 12140, 12406, 12665, 12916, 13160, 13395, 13623, 13842,
  1098. +14053, 14256, 14449, 14635, 14811, 14978, 15137, 15286, 15426,
  1099. +15557, 15679, 15791, 15893, 15986, 16069, 16143, 16207, 16261,
  1100. +16305, 16340, 16364, 16379
  1101. +};
  1102. diff -Naur supertux-0.1.3/src.bak/fpmath.h supertux-0.1.3/src/fpmath.h
  1103. --- supertux-0.1.3/src.bak/fpmath.h 1969-12-31 19:00:00.000000000 -0500
  1104. +++ supertux-0.1.3/src/fpmath.h 2014-12-06 18:04:18.000000000 -0500
  1105. @@ -0,0 +1,73 @@
  1106. +//  $Id: fpmath.h,v Exp $
  1107. +//
  1108. +//  SuperTux -  A Jump'n Run
  1109. +//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
  1110. +//
  1111. +//  This program is free software; you can redistribute it and/or
  1112. +//  modify it under the terms of the GNU General Public License
  1113. +//  as published by the Free Software Foundation; either version 2
  1114. +//  of the License, or (at your option) any later version.
  1115. +//
  1116. +//  This program is distributed in the hope that it will be useful,
  1117. +//  but WITHOUT ANY WARRANTY; without even the implied warranty of
  1118. +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1119. +//  GNU General Public License for more details.
  1120. +//
  1121. +//  You should have received a copy of the GNU General Public License
  1122. +//  along with this program; if not, write to the Free Software
  1123. +//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  1124. +
  1125. +#ifndef FPMATH_H
  1126. +#define FPMATH_H
  1127. +
  1128. +typedef long fp;
  1129. +
  1130. +// Number of bits behind the comma
  1131. +#define FP 14
  1132. +#define FPH 7
  1133. +#define FP_FULL 0x4000
  1134. +#define FP_HALF 0x80
  1135. +
  1136. +#define int2fp(exp) ((exp) << 14)
  1137. +#define fp2int(exp) ((exp) >> 14)
  1138. +
  1139. +// Fractional part of the fixed point number
  1140. +#define fpfract(exp) ((exp) & 0x3FFF)
  1141. +
  1142. +#define fp2float(exp) (((double)(exp)) / (1 << 14))
  1143. +#define float2fp(exp) ((fp) ((exp) * (1 << 14)))
  1144. +
  1145. +// Inline functions
  1146. +static inline fp fpmul(fp a, fp b) {
  1147. +//ifndef HAVE_LONG_LONG
  1148. +//    int aa = a & (FP_HALF-1);
  1149. +//    a = a >> FPH;
  1150. +//    int bb = b & (FP_HALF-1);
  1151. +//    b = b >> FPH;
  1152. +//    return a*b + ((aa*b + a*bb) >> FPH);
  1153. +//else
  1154. +    long long r = (long long)a * (long long)b;
  1155. +    return (fp)(r >> FP);
  1156. +//endif
  1157. +}
  1158. +
  1159. +static inline fp fpdiv(fp a, fp b) {
  1160. +//ifndef HAVE_LONG_LONG
  1161. +//    if (b < FP_FULL)
  1162. +//        return fpmul(a, FP_FULL/b);
  1163. +//    else
  1164. +//        return a / fp2int(b);
  1165. +//else
  1166. +    long long la = (long long)a << FP;
  1167. +    return (fp)(la / (long long)b);
  1168. +//endif
  1169. +}
  1170. +
  1171. +// Lookup table based functions
  1172. +extern fp sine[];
  1173. +extern fp cosine[];
  1174. +
  1175. +#define fpsin(exp) (sine[(exp) & 0xFF])
  1176. +#define fpcos(exp) (cosine[(exp) & 0xFF])
  1177. +
  1178. +#endif
  1179. diff -Naur supertux-0.1.3/src.bak/gameloop.cpp supertux-0.1.3/src/gameloop.cpp
  1180. --- supertux-0.1.3/src.bak/gameloop.cpp 2014-12-06 18:00:56.000000000 -0500
  1181. +++ supertux-0.1.3/src/gameloop.cpp 2014-12-06 19:01:42.000000000 -0500
  1182. @@ -54,6 +54,7 @@
  1183.  #include "particlesystem.h"
  1184.  #include "resources.h"
  1185.  #include "music_manager.h"
  1186. +#include "fpmath.h"
  1187.  
  1188.  GameSession* GameSession::current_ = 0;
  1189.  
  1190. @@ -82,7 +83,7 @@
  1191.    fps_timer.init(true);
  1192.    frame_timer.init(true);
  1193.  
  1194. -  float old_x_pos = -1;
  1195. +  fp old_x_pos = int2fp(-1);
  1196.  
  1197.    if (world)
  1198.      { // Tux has lost a life, so we try to respawn him at the nearest reset point
  1199. @@ -105,20 +106,20 @@
  1200.      }
  1201.  
  1202.    // Set Tux to the nearest reset point
  1203. -  if (old_x_pos != -1)
  1204. +  if (old_x_pos != int2fp(-1))
  1205.      {
  1206.        ResetPoint best_reset_point = { -1, -1 };
  1207.        for(std::vector<ResetPoint>::iterator i = get_level()->reset_points.begin();
  1208.            i != get_level()->reset_points.end(); ++i)
  1209.          {
  1210. -          if (i->x - screen->w/2 < old_x_pos && best_reset_point.x < i->x)
  1211. +          if (int2fp(i->x) - screen->w/2 < old_x_pos && best_reset_point.x < i->x)
  1212.              best_reset_point = *i;
  1213.          }
  1214.        
  1215.        if (best_reset_point.x != -1)
  1216.          {
  1217. -          world->get_tux()->base.x = best_reset_point.x;
  1218. -          world->get_tux()->base.y = best_reset_point.y;
  1219. +          world->get_tux()->base.x = int2fp(best_reset_point.x);
  1220. +          world->get_tux()->base.y = int2fp(best_reset_point.y);
  1221.            world->get_tux()->old_base = world->get_tux()->base;
  1222.            world->get_tux()->previous_base = world->get_tux()->base;
  1223.  
  1224. @@ -126,7 +127,7 @@
  1225.                std::cout << "Warning: reset point inside a wall.\n";
  1226.            }                                                                  
  1227.  
  1228. -          scroll_x = best_reset_point.x - screen->w/2;
  1229. +          scroll_x = int2fp(best_reset_point.x - screen->w/2);
  1230.          }
  1231.      }
  1232.      
  1233. @@ -212,7 +213,7 @@
  1234.        tux.input.right = DOWN;
  1235.        tux.input.down  = UP;
  1236.  
  1237. -      if (int(last_x_pos) == int(tux.base.x))
  1238. +      if (fp2int(last_x_pos) == fp2int(tux.base.x))
  1239.          tux.input.up    = DOWN;
  1240.        else
  1241.          tux.input.up    = UP;
  1242. @@ -340,10 +341,10 @@
  1243.                              tux.size = !tux.size;
  1244.                              if(tux.size == BIG)
  1245.                                {
  1246. -                                tux.base.height = 64;
  1247. +                                tux.base.height = int2fp(64);
  1248.                                }
  1249.                              else
  1250. -                              tux.base.height = 32;
  1251. +                              tux.base.height = int2fp(32);
  1252.                            }
  1253.                          break;
  1254.                        case SDLK_END:
  1255. @@ -507,33 +508,48 @@
  1256.    Tile* endtile = collision_goal(tux->base);
  1257.  
  1258.    // fallback in case the other endpositions don't trigger
  1259. -  if (!end_sequence && tux->base.x >= endpos)
  1260. +  if (!end_sequence && tux->base.x >= int2fp(endpos))
  1261.      {
  1262. +      if (debug_mode) {
  1263. +       printf("\nEnd sequence WAITING triggered\n");
  1264. +      }
  1265.        end_sequence = ENDSEQUENCE_WAITING;
  1266. -      last_x_pos = -1;
  1267. +      last_x_pos = int2fp(-1);
  1268.        music_manager->play_music(level_end_song, 0);
  1269.        endsequence_timer.start(7000);
  1270.        tux->invincible_timer.start(7000); //FIXME: Implement a winning timer for the end sequence (with special winning animation etc.)
  1271.      }
  1272.    else if(end_sequence && !endsequence_timer.check())
  1273.      {
  1274. +      if (debug_mode) {
  1275. +       printf("End sequence finished\n");
  1276. +      }
  1277.        exit_status = ES_LEVEL_FINISHED;
  1278.        return;
  1279.      }
  1280.    else if(end_sequence == ENDSEQUENCE_RUNNING && endtile && endtile->data >= 1)
  1281.      {
  1282. +      if (debug_mode) {
  1283. +       printf("End sequence switched from RUNNING to WAITING\n");
  1284. +      }
  1285.        end_sequence = ENDSEQUENCE_WAITING;
  1286.      }
  1287.    else if(!end_sequence && endtile && endtile->data == 0)
  1288.      {
  1289. +      if (debug_mode) {
  1290. +       printf("\nEnd sequence RUNNING triggered\n");
  1291. +      }
  1292.        end_sequence = ENDSEQUENCE_RUNNING;
  1293. -      last_x_pos = -1;
  1294. +      last_x_pos = int2fp(-1);
  1295.        music_manager->play_music(level_end_song, 0);
  1296.        endsequence_timer.start(7000); // 5 seconds until we finish the map
  1297.        tux->invincible_timer.start(7000); //FIXME: Implement a winning timer for the end sequence (with special winning animation etc.)
  1298.      }
  1299.    else if (!end_sequence && tux->is_dead())
  1300.      {
  1301. +      if (debug_mode) {
  1302. +       printf("\nEnd sequence death triggered\n");
  1303. +      }
  1304.        player_status.bonus = PlayerStatus::NO_BONUS;
  1305.  
  1306.        if (player_status.lives < 0)
  1307. @@ -553,7 +569,7 @@
  1308.  }
  1309.  
  1310.  void
  1311. -GameSession::action(double frame_ratio)
  1312. +GameSession::action(fp frame_ratio)
  1313.  {
  1314.    if (exit_status == ES_NONE)
  1315.      {
  1316. @@ -640,7 +656,7 @@
  1317.      {
  1318.        SDL_Delay(10);
  1319.        /* Calculate the movement-factor */
  1320. -      double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
  1321. +      fp frame_ratio = (int2fp(update_time-last_update_time))/(FRAME_RATE);
  1322.  
  1323.        if(!frame_timer.check())
  1324.          {
  1325. @@ -718,7 +734,7 @@
  1326.        if(show_fps)
  1327.          {
  1328.            ++fps_cnt;
  1329. -          fps_fps = (1000.0 / (float)fps_timer.get_gone()) * (float)fps_cnt;
  1330. +          fps_fps = int2fp(fps_cnt) * 1000 / fps_timer.get_gone();
  1331.  
  1332.            if(!fps_timer.check())
  1333.              {
  1334. @@ -733,10 +749,10 @@
  1335.  }
  1336.  
  1337.  /* Bounce a brick: */
  1338. -void bumpbrick(float x, float y)
  1339. +void bumpbrick(fp x, fp y)
  1340.  {
  1341. -  World::current()->add_bouncy_brick(((int)(x + 1) / (32)) * (32),
  1342. -                         (int)(y / (32)) * (32));
  1343. +  World::current()->add_bouncy_brick(int2fp(((fp2int(x) + 1) / 32) * 32),
  1344. +                                     int2fp((fp2int(y) / 32) * 32));
  1345.  
  1346.  #ifndef GP2X
  1347.    play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
  1348. @@ -799,7 +815,7 @@
  1349.  
  1350.    if(show_fps)
  1351.      {
  1352. -      sprintf(str, "%2.1f", fps_fps);
  1353. +      sprintf(str, "%2.1f", fp2float(fps_fps));
  1354.        white_text->draw("FPS", screen->h, 40, 1);
  1355.        gold_text->draw(str, screen->h + 60, 40, 1);
  1356.      }
  1357. diff -Naur supertux-0.1.3/src.bak/gameloop.h supertux-0.1.3/src/gameloop.h
  1358. --- supertux-0.1.3/src.bak/gameloop.h   2014-12-06 18:00:56.000000000 -0500
  1359. +++ supertux-0.1.3/src/gameloop.h   2014-12-06 18:04:18.000000000 -0500
  1360. @@ -26,6 +26,7 @@
  1361.  #include "type.h"
  1362.  #include "level.h"
  1363.  #include "world.h"
  1364. +#include "fpmath.h"
  1365.  
  1366.  /* GameLoop modes */
  1367.  
  1368. @@ -51,7 +52,7 @@
  1369.    World* world;
  1370.    int st_gl_mode;
  1371.    int levelnb;
  1372. -  float fps_fps;
  1373. +  fp fps_fps;
  1374.    unsigned int last_update_time;
  1375.    unsigned int update_time;
  1376.    int pause_menu_frame;
  1377. @@ -65,7 +66,7 @@
  1378.      ENDSEQUENCE_WAITING  // waiting for the end of the music
  1379.    };
  1380.    EndSequenceState end_sequence;
  1381. -  float last_x_pos;
  1382. +  fp last_x_pos;
  1383.  
  1384.    bool game_pause;
  1385.  
  1386. @@ -87,7 +88,7 @@
  1387.    ExitStatus run();
  1388.  
  1389.    void draw();
  1390. -  void action(double frame_ratio);
  1391. +  void action(fp frame_ratio);
  1392.  
  1393.    Level* get_level() { return world->get_level(); }
  1394.    World* get_world() { return world; }
  1395. @@ -115,7 +116,7 @@
  1396.  std::string slotinfo(int slot);
  1397.  
  1398.  bool rectcollision(base_type* one, base_type* two);
  1399. -void bumpbrick(float x, float y);
  1400. +void bumpbrick(fp x, fp y);
  1401.  
  1402.  #endif /*SUPERTUX_GAMELOOP_H*/
  1403.  
  1404. diff -Naur supertux-0.1.3/src.bak/gameobjs.cpp supertux-0.1.3/src/gameobjs.cpp
  1405. --- supertux-0.1.3/src.bak/gameobjs.cpp 2014-12-06 18:00:56.000000000 -0500
  1406. +++ supertux-0.1.3/src/gameobjs.cpp 2014-12-06 19:09:42.000000000 -0500
  1407. @@ -24,21 +24,22 @@
  1408.  #include "tile.h"
  1409.  #include "gameloop.h"
  1410.  #include "gameobjs.h"
  1411. +#include "fpmath.h"
  1412.  
  1413.  void
  1414. -BouncyDistro::init(float x, float y)
  1415. +BouncyDistro::init(fp x, fp y)
  1416.  {
  1417.    base.x = x;
  1418.    base.y = y;
  1419. -  base.ym = -2;
  1420. +  base.ym = int2fp(-2);
  1421.  }
  1422.  
  1423.  void
  1424. -BouncyDistro::action(double frame_ratio)
  1425. +BouncyDistro::action(fp frame_ratio)
  1426.  {
  1427. -  base.y = base.y + base.ym * frame_ratio;
  1428. +  base.y = base.y + fpmul(base.ym, frame_ratio);
  1429.  
  1430. -  base.ym += 0.1 * frame_ratio;
  1431. +  base.ym += frame_ratio / 10;
  1432.  
  1433.    if (base.ym >= 0)
  1434.      {
  1435. @@ -54,13 +55,13 @@
  1436.  void
  1437.  BouncyDistro::draw()
  1438.  {
  1439. -  img_distro[0]->draw(base.x - scroll_x,
  1440. -                      base.y);
  1441. +  img_distro[0]->draw(fp2int(base.x - scroll_x),
  1442. +                      fp2int(base.y));
  1443.  }
  1444.  
  1445.  
  1446.  void
  1447. -BrokenBrick::init(Tile* tile_, float x, float y, float xm, float ym)
  1448. +BrokenBrick::init(Tile* tile_, fp x, fp y, fp xm, fp ym)
  1449.  {
  1450.    tile    = tile_;
  1451.    base.x  = x;
  1452. @@ -73,10 +74,10 @@
  1453.  }
  1454.  
  1455.  void
  1456. -BrokenBrick::action(double frame_ratio)
  1457. +BrokenBrick::action(fp frame_ratio)
  1458.  {
  1459. -  base.x = base.x + base.xm * frame_ratio;
  1460. -  base.y = base.y + base.ym * frame_ratio;
  1461. +  base.x = base.x + fpmul(base.xm, frame_ratio);
  1462. +  base.y = base.y + fpmul(base.ym, frame_ratio);
  1463.  
  1464.    if (!timer.check())
  1465.      {
  1466. @@ -98,11 +99,11 @@
  1467.    src.w = 16;
  1468.    src.h = 16;
  1469.  
  1470. -  dest.x = (int)(base.x - scroll_x);
  1471. +  dest.x = fp2int(base.x - scroll_x);
  1472.  #ifdef RES320X240
  1473.    dest.x=dest.x/2;
  1474.  #endif
  1475. -  dest.y = (int)base.y;
  1476. +  dest.y = fp2int(base.y);
  1477.    dest.w = 16;
  1478.    dest.h = 16;
  1479.    
  1480. @@ -111,23 +112,23 @@
  1481.  }
  1482.  
  1483.  void
  1484. -BouncyBrick::init(float x, float y)
  1485. +BouncyBrick::init(fp x, fp y)
  1486.  {
  1487.    base.x   = x;
  1488.    base.y   = y;
  1489.    offset   = 0;
  1490. -  offset_m = -BOUNCY_BRICK_SPEED;
  1491. -  shape    = World::current()->get_level()->gettileid(x, y);
  1492. +  offset_m = -FP_BOUNCY_BRICK_SPEED;
  1493. +  shape    = World::current()->get_level()->gettileid(fp2int(x), fp2int(y));
  1494.  }
  1495.  
  1496.  void
  1497. -BouncyBrick::action(double frame_ratio)
  1498. +BouncyBrick::action(fp frame_ratio)
  1499.  {
  1500. -  offset = (offset + offset_m * frame_ratio);
  1501. +  offset = (offset + fpmul(offset_m, frame_ratio));
  1502.  
  1503.    /* Go back down? */
  1504. -  if (offset < -BOUNCY_BRICK_MAX_OFFSET)
  1505. -    offset_m = BOUNCY_BRICK_SPEED;
  1506. +  if (offset < -FP_BOUNCY_BRICK_MAX_OFFSET)
  1507. +    offset_m = FP_BOUNCY_BRICK_SPEED;
  1508.  
  1509.  
  1510.    /* Stop bouncing? */
  1511. @@ -148,15 +149,15 @@
  1512.    SDL_Rect dest;
  1513.    
  1514.  #ifndef RES320X240
  1515. -  if (base.x >= scroll_x - 32 &&
  1516. -      base.x <= scroll_x + screen->w)
  1517. +  if (base.x >= scroll_x - int2fp(32) &&
  1518. +      base.x <= scroll_x + int2fp(screen->w))
  1519.  #else
  1520.    if (base.x >= scroll_x - 32 &&
  1521.        base.x <= scroll_x + 640)
  1522.  #endif
  1523.      {
  1524. -      dest.x = (int)(base.x - scroll_x);
  1525. -      dest.y = (int)base.y;
  1526. +      dest.x = fp2int(base.x - scroll_x);
  1527. +      dest.y = fp2int(base.y);
  1528.        dest.w = 32;
  1529.        dest.h = 32;
  1530.  
  1531. @@ -166,14 +167,14 @@
  1532.        // paint it later at on offseted position
  1533.        if(plevel->bkgd_image[0] == '\0')
  1534.          {
  1535. -          fillrect(base.x - scroll_x, base.y,
  1536. +          fillrect(fp2int(base.x - scroll_x), fp2int(base.y),
  1537.                     32,32,
  1538.                     plevel->bkgd_top.red, plevel->bkgd_top.green, plevel->bkgd_top.blue, 0);
  1539.  // FIXME: doesn't respect the gradient, futhermore is this necessary at all??
  1540.          }
  1541.        else
  1542.          {
  1543. -          int s = ((int)scroll_x / 2)%640;
  1544. +          int s = (fp2int(scroll_x) / 2)%640;
  1545.  
  1546.  #ifdef RES320X240
  1547.            plevel->img_bkgd->draw_part(dest.x/2 + s/2, dest.y/2,
  1548. @@ -184,14 +185,14 @@
  1549.  #endif
  1550.          }
  1551.  
  1552. -      Tile::draw(base.x - scroll_x,
  1553. -                 base.y + offset,
  1554. +      Tile::draw(fp2int(base.x - scroll_x),
  1555. +                 fp2int(base.y + offset),
  1556.                   shape);
  1557.      }
  1558.  }
  1559.  
  1560.  void
  1561. -FloatingScore::init(float x, float y, int s)
  1562. +FloatingScore::init(fp x, fp y, int s)
  1563.  {
  1564.    base.x = x;
  1565.    base.y = y - 16;
  1566. @@ -201,7 +202,7 @@
  1567.  }
  1568.  
  1569.  void
  1570. -FloatingScore::action(double frame_ratio)
  1571. +FloatingScore::action(fp frame_ratio)
  1572.  {
  1573.    base.y = base.y - 2 * frame_ratio;
  1574.  
  1575. @@ -221,7 +222,7 @@
  1576.  {
  1577.    char str[10];
  1578.    sprintf(str, "%d", value);
  1579. -  gold_text->draw(str, (int)base.x + 16 - strlen(str) * 8, (int)base.y, 1);
  1580. +  gold_text->draw(str, fp2int(base.x) + 16 - strlen(str) * 8, fp2int(base.y), 1);
  1581.  }
  1582.  
  1583.  /* EOF */
  1584. diff -Naur supertux-0.1.3/src.bak/gameobjs.h supertux-0.1.3/src/gameobjs.h
  1585. --- supertux-0.1.3/src.bak/gameobjs.h   2014-12-06 18:00:56.000000000 -0500
  1586. +++ supertux-0.1.3/src/gameobjs.h   2014-12-06 18:04:19.000000000 -0500
  1587. @@ -26,6 +26,7 @@
  1588.  #include "texture.h"
  1589.  #include "timer.h"
  1590.  #include "scene.h"
  1591. +#include "fpmath.h"
  1592.  
  1593.  /* Bounciness of distros: */
  1594.  #define NO_BOUNCE 0
  1595. @@ -35,17 +36,14 @@
  1596.  {
  1597.   public:
  1598.    
  1599. -  void init(float x, float y);
  1600. -  void action(double frame_ratio);
  1601. +  void init(fp x, fp y);
  1602. +  void action(fp frame_ratio);
  1603.    void draw();
  1604.    std::string type() { return "BouncyDistro"; };
  1605.  };
  1606.  
  1607.  extern Surface* img_distro[4];
  1608.  
  1609. -#define BOUNCY_BRICK_MAX_OFFSET 8
  1610. -#define BOUNCY_BRICK_SPEED 0.9
  1611. -
  1612.  class Tile;
  1613.  
  1614.  class BrokenBrick : public GameObject
  1615. @@ -54,8 +52,8 @@
  1616.    Timer timer;
  1617.    Tile* tile;
  1618.  
  1619. -  void init(Tile* tile, float x, float y, float xm, float ym);
  1620. -  void action(double frame_ratio);
  1621. +  void init(Tile* tile, fp x, fp y, fp xm, fp ym);
  1622. +  void action(fp frame_ratio);
  1623.    void draw();
  1624.    std::string type() { return "BrokenBrick"; };
  1625.  };
  1626. @@ -63,12 +61,12 @@
  1627.  class BouncyBrick : public GameObject
  1628.  {
  1629.   public:
  1630. -  float offset;
  1631. -  float offset_m;
  1632. +  fp offset;
  1633. +  fp offset_m;
  1634.    int shape;
  1635.  
  1636. -  void init(float x, float y);
  1637. -  void action(double frame_ratio);
  1638. +  void init(fp x, fp y);
  1639. +  void action(fp frame_ratio);
  1640.    void draw();
  1641.    std::string type() { return "BouncyBrick"; };
  1642.  };
  1643. @@ -79,8 +77,8 @@
  1644.    int value;
  1645.    Timer timer;
  1646.    
  1647. -  void init(float x, float y, int s);
  1648. -  void action(double frame_ratio);
  1649. +  void init(fp x, fp y, int s);
  1650. +  void action(fp frame_ratio);
  1651.    void draw();
  1652.    std::string type() { return "FloatingScore"; };
  1653.  };
  1654. diff -Naur supertux-0.1.3/src.bak/globals.cpp supertux-0.1.3/src/globals.cpp
  1655. --- supertux-0.1.3/src.bak/globals.cpp  2014-12-06 18:00:56.000000000 -0500
  1656. +++ supertux-0.1.3/src/globals.cpp  2014-12-06 18:04:19.000000000 -0500
  1657. @@ -68,7 +68,7 @@
  1658.  bool use_fullscreen;
  1659.  bool debug_mode;
  1660.  bool show_fps;
  1661. -float game_speed = 1.0f;
  1662. +//float game_speed = 1.0f;
  1663.  
  1664.  int joystick_num = 0;
  1665.  char* level_startup_file = 0;
  1666. diff -Naur supertux-0.1.3/src.bak/globals.h supertux-0.1.3/src/globals.h
  1667. --- supertux-0.1.3/src.bak/globals.h    2014-12-06 18:00:56.000000000 -0500
  1668. +++ supertux-0.1.3/src/globals.h    2014-12-06 18:04:19.000000000 -0500
  1669. @@ -111,7 +111,7 @@
  1670.  extern char* st_dir;
  1671.  extern char* st_save_dir;
  1672.  
  1673. -extern float game_speed;
  1674. +//extern float game_speed;
  1675.  extern SDL_Joystick * js;
  1676.  
  1677.  int wait_for_event(SDL_Event& event,unsigned int min_delay = 0, unsigned int max_delay = 0, bool empty_events = false);
  1678. diff -Naur supertux-0.1.3/src.bak/intro.cpp supertux-0.1.3/src/intro.cpp
  1679. --- supertux-0.1.3/src.bak/intro.cpp    2014-12-06 18:00:56.000000000 -0500
  1680. +++ supertux-0.1.3/src/intro.cpp    2014-12-06 18:04:19.000000000 -0500
  1681. @@ -37,6 +37,6 @@
  1682.  {
  1683.  if(debug_mode)
  1684.    fade("/images/background/arctis2.jpg", 30, false);
  1685. -display_text_file("intro.txt", "/images/background/arctis2.jpg", SCROLL_SPEED_MESSAGE);
  1686. +display_text_file("intro.txt", "/images/background/arctis2.jpg", FP_SCROLL_SPEED_MESSAGE);
  1687.  }
  1688.  
  1689. diff -Naur supertux-0.1.3/src.bak/level.cpp supertux-0.1.3/src/level.cpp
  1690. --- supertux-0.1.3/src.bak/level.cpp    2014-12-06 18:00:56.000000000 -0500
  1691. +++ supertux-0.1.3/src/level.cpp    2014-12-06 18:04:19.000000000 -0500
  1692. @@ -23,6 +23,7 @@
  1693.  #include <stdio.h>
  1694.  #include <string.h>
  1695.  #include <iostream>
  1696. +#include <zlib.h>
  1697.  #include "globals.h"
  1698.  #include "setup.h"
  1699.  #include "screen.h"
  1700. @@ -33,6 +34,7 @@
  1701.  #include "lispreader.h"
  1702.  #include "resources.h"
  1703.  #include "music_manager.h"
  1704. +#include "fpmath.h"
  1705.  
  1706.  using namespace std;
  1707.  
  1708. @@ -92,7 +94,8 @@
  1709.  
  1710.  void LevelSubset::load(char *subset)
  1711.  {
  1712. -  FILE* fi;
  1713. +  //FILE* fi;
  1714. +  gzFile fi;
  1715.    char filename[1024];
  1716.    char str[1024];
  1717.    int i;
  1718. @@ -105,13 +108,14 @@
  1719.      snprintf(filename, 1024, "%s/levels/%s/info", datadir.c_str(), subset);
  1720.    if(faccessible(filename))
  1721.      {
  1722. -      fi = fopen(filename, "r");
  1723. +      fi = gzopen(filename, "r");
  1724.        if (fi == NULL)
  1725.          {
  1726.            perror(filename);
  1727.          }
  1728. +
  1729.        lisp_stream_t stream;
  1730. -      lisp_stream_init_file (&stream, fi);
  1731. +      lisp_stream_init_gzfile (&stream, fi);
  1732.        root_obj = lisp_read (&stream);
  1733.  
  1734.        if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
  1735. @@ -133,7 +137,7 @@
  1736.          }
  1737.  
  1738.        lisp_free(root_obj);
  1739. -      fclose(fi);
  1740. +      gzclose(fi);
  1741.  
  1742.        snprintf(str, 1024, "%s.png", filename);
  1743.        if(faccessible(str))
  1744. @@ -153,19 +157,30 @@
  1745.      {
  1746.        /* Get the number of levels in this subset */
  1747.        snprintf(filename, 1024, "%s/levels/%s/level%d.stl", st_dir, subset,i);
  1748. -      if(!faccessible(filename))
  1749. -        {
  1750. -          snprintf(filename, 1024, "%s/levels/%s/level%d.stl", datadir.c_str(), subset,i);
  1751. -          if(!faccessible(filename))
  1752. -            break;
  1753. -        }
  1754. +      if(faccessible(filename))
  1755. +        continue;
  1756. +
  1757. +      snprintf(filename, 1024, "%s/levels/%s/level%d.stl.gz", st_dir, subset,i);
  1758. +      if(faccessible(filename))
  1759. +        continue;
  1760. +
  1761. +      snprintf(filename, 1024, "%s/levels/%s/level%d.stl", datadir.c_str(), subset,i);
  1762. +      if(faccessible(filename))
  1763. +        continue;
  1764. +
  1765. +      snprintf(filename, 1024, "%s/levels/%s/level%d.stl.gz", datadir.c_str(), subset,i);
  1766. +      if(faccessible(filename))
  1767. +        continue;
  1768. +
  1769. +      break;
  1770.      }
  1771.    levels = --i;
  1772.  }
  1773.  
  1774.  void LevelSubset::save()
  1775.  {
  1776. -  FILE* fi;
  1777. +  //FILE* fi;
  1778. +  gzFile fi;
  1779.    string filename;
  1780.  
  1781.    /* Save data file: */
  1782. @@ -177,24 +192,24 @@
  1783.      filename = datadir + "/levels/" + name + "/info";
  1784.    if(fwriteable(filename.c_str()))
  1785.      {
  1786. -      fi = fopen(filename.c_str(), "w");
  1787. +      fi = gzopen(filename.c_str(), "w");
  1788.        if (fi == NULL)
  1789.          {
  1790.            perror(filename.c_str());
  1791.          }
  1792.  
  1793.        /* Write header: */
  1794. -      fprintf(fi,";SuperTux-Level-Subset\n");
  1795. -      fprintf(fi,"(supertux-level-subset\n");
  1796. +      gzprintf(fi,";SuperTux-Level-Subset\n");
  1797. +      gzprintf(fi,"(supertux-level-subset\n");
  1798.  
  1799.        /* Save title info: */
  1800. -      fprintf(fi,"  (title \"%s\")\n", title.c_str());
  1801. +      gzprintf(fi,"  (title \"%s\")\n", title.c_str());
  1802.  
  1803.        /* Save the description: */
  1804. -      fprintf(fi,"  (description \"%s\")\n", description.c_str());
  1805. +      gzprintf(fi,"  (description \"%s\")\n", description.c_str());
  1806.  
  1807. -      fprintf( fi,")");
  1808. -      fclose(fi);
  1809. +      gzprintf( fi,")");
  1810. +      gzclose(fi);
  1811.  
  1812.      }
  1813.  }
  1814. @@ -235,7 +250,7 @@
  1815.    start_pos_x = 100;
  1816.    start_pos_y = 170;
  1817.    time_left  = 100;
  1818. -  gravity    = 10.;
  1819. +  gravity    = int2fp(10);
  1820.    back_scrolling = false;
  1821.    hor_autoscroll_speed = 0;
  1822.    bkgd_speed = 50;
  1823. @@ -274,7 +289,11 @@
  1824.    // Load data file:
  1825.    snprintf(filename, 1024, "%s/levels/%s/level%d.stl", st_dir, subset.c_str(), level);
  1826.    if(!faccessible(filename))
  1827. -    snprintf(filename, 1024, "%s/levels/%s/level%d.stl", datadir.c_str(), subset.c_str(), level);
  1828. +    snprintf(filename, 1024, "%s/levels/%s/level%d.stl.gz", datadir.c_str(), subset.c_str(), level);
  1829. +  if(!faccessible(filename))
  1830. +    snprintf(filename, 1024, "%s/levels/%s/level%d.stl", st_dir, subset.c_str(), level);
  1831. +  if(!faccessible(filename))
  1832. +    snprintf(filename, 1024, "%s/levels/%s/level%d.stl.gz", datadir.c_str(), subset.c_str(), level);
  1833.  
  1834.    return load(filename);
  1835.  }
  1836. @@ -317,8 +336,9 @@
  1837.        back_scrolling = false;
  1838.        reader.read_bool("back_scrolling",  &back_scrolling);
  1839.  
  1840. -      hor_autoscroll_speed = 0;
  1841. -      reader.read_float("hor_autoscroll_speed",  &hor_autoscroll_speed);
  1842. +      float hor_autoscroll_speed_f = 0;
  1843. +      reader.read_float("hor_autoscroll_speed",  &hor_autoscroll_speed_f);
  1844. +      hor_autoscroll_speed = float2fp(hor_autoscroll_speed_f);
  1845.        
  1846.        bkgd_speed = 50;
  1847.        reader.read_int("bkgd_speed",  &bkgd_speed);
  1848. @@ -334,8 +354,10 @@
  1849.        reader.read_int("bkgd_green_bottom",  &bkgd_bottom.green);
  1850.        reader.read_int("bkgd_blue_bottom",  &bkgd_bottom.blue);
  1851.  
  1852. -      gravity = 10;
  1853. -      reader.read_float("gravity",  &gravity);
  1854. +      float gravity_f = 10;
  1855. +      reader.read_float("gravity",  &gravity_f);
  1856. +      gravity = float2fp(gravity_f);
  1857. +      
  1858.        name = "Noname";
  1859.        reader.read_string("name",  &name);
  1860.        author = "unknown author";
  1861. @@ -549,11 +571,18 @@
  1862.    fcreatedir(str);
  1863.    snprintf(filename, 1024, "%s/levels/%s/level%d.stl", st_dir, subset.c_str(),
  1864.        level);
  1865. -  if(!fwriteable(filename))
  1866. +  if(!faccessible(filename)) // write to .gz if no file exists
  1867. +    snprintf(filename, 1024, "%s/levels/%s/level%d.stl.gz", st_dir, subset.c_str(),
  1868. +        level);
  1869. +  if(!fwriteable(filename)) {
  1870.      snprintf(filename, 1024, "%s/levels/%s/level%d.stl", datadir.c_str(),
  1871.          subset.c_str(), level);
  1872. +    if(!faccessible(filename)) // write to .gz if no file exists
  1873. +      snprintf(filename, 1024, "%s/levels/%s/level%d.stl.gz", datadir.c_str(),
  1874. +          subset.c_str(), level);
  1875. +  }
  1876.  
  1877. -  FILE * fi = fopen(filename, "w");
  1878. +  gzFile fi = gzopen(filename, "w");
  1879.    if (fi == NULL)
  1880.      {
  1881.        perror(filename);
  1882. @@ -563,78 +592,78 @@
  1883.  
  1884.  
  1885.    /* Write header: */
  1886. -  fprintf(fi,";SuperTux-Level\n");
  1887. -  fprintf(fi,"(supertux-level\n");
  1888. +  gzprintf(fi,";SuperTux-Level\n");
  1889. +  gzprintf(fi,"(supertux-level\n");
  1890.  
  1891. -  fprintf(fi,"  (version %d)\n", 1);
  1892. -  fprintf(fi,"  (name \"%s\")\n", name.c_str());
  1893. -  fprintf(fi,"  (author \"%s\")\n", author.c_str());
  1894. -  fprintf(fi,"  (music \"%s\")\n", song_title.c_str());
  1895. -  fprintf(fi,"  (background \"%s\")\n", bkgd_image.c_str());
  1896. -  fprintf(fi,"  (particle_system \"%s\")\n", particle_system.c_str());
  1897. -  fprintf(fi,"  (bkgd_speed %d)\n", bkgd_speed);
  1898. -  fprintf(fi,"  (bkgd_red_top %d)\n", bkgd_top.red);
  1899. -  fprintf(fi,"  (bkgd_green_top %d)\n", bkgd_top.green);
  1900. -  fprintf(fi,"  (bkgd_blue_top %d)\n", bkgd_top.blue);
  1901. -  fprintf(fi,"  (bkgd_red_bottom %d)\n", bkgd_bottom.red);
  1902. -  fprintf(fi,"  (bkgd_green_bottom %d)\n", bkgd_bottom.green);
  1903. -  fprintf(fi,"  (bkgd_blue_bottom %d)\n", bkgd_bottom.blue);
  1904. -  fprintf(fi,"  (time %d)\n", time_left);
  1905. -  fprintf(fi,"  (width %d)\n", width);
  1906. +  gzprintf(fi,"  (version %d)\n", 1);
  1907. +  gzprintf(fi,"  (name \"%s\")\n", name.c_str());
  1908. +  gzprintf(fi,"  (author \"%s\")\n", author.c_str());
  1909. +  gzprintf(fi,"  (music \"%s\")\n", song_title.c_str());
  1910. +  gzprintf(fi,"  (background \"%s\")\n", bkgd_image.c_str());
  1911. +  gzprintf(fi,"  (particle_system \"%s\")\n", particle_system.c_str());
  1912. +  gzprintf(fi,"  (bkgd_speed %d)\n", bkgd_speed);
  1913. +  gzprintf(fi,"  (bkgd_red_top %d)\n", bkgd_top.red);
  1914. +  gzprintf(fi,"  (bkgd_green_top %d)\n", bkgd_top.green);
  1915. +  gzprintf(fi,"  (bkgd_blue_top %d)\n", bkgd_top.blue);
  1916. +  gzprintf(fi,"  (bkgd_red_bottom %d)\n", bkgd_bottom.red);
  1917. +  gzprintf(fi,"  (bkgd_green_bottom %d)\n", bkgd_bottom.green);
  1918. +  gzprintf(fi,"  (bkgd_blue_bottom %d)\n", bkgd_bottom.blue);
  1919. +  gzprintf(fi,"  (time %d)\n", time_left);
  1920. +  gzprintf(fi,"  (width %d)\n", width);
  1921.    if(back_scrolling)
  1922. -    fprintf(fi,"  (back_scrolling #t)\n");
  1923. +    gzprintf(fi,"  (back_scrolling #t)\n");
  1924.    else
  1925. -    fprintf(fi,"  (back_scrolling #f)\n");
  1926. -  fprintf(fi,"  (hor_autoscroll_speed %2.1f)\n", hor_autoscroll_speed);
  1927. -  fprintf(fi,"  (gravity %2.1f)\n", gravity);
  1928. -  fprintf(fi,"  (background-tm ");
  1929. +    gzprintf(fi,"  (back_scrolling #f)\n");
  1930. +  gzprintf(fi,"  (hor_autoscroll_speed %2.1f)\n", fp2float(hor_autoscroll_speed));
  1931. +  gzprintf(fi,"  (gravity %2.1f)\n", fp2float(gravity));
  1932. +  gzprintf(fi,"  (background-tm ");
  1933.  
  1934.    for(int y = 0; y < 15; ++y)
  1935.      {
  1936.        for(int i = 0; i < width; ++i)
  1937. -        fprintf(fi," %d ", bg_tiles[y][i]);
  1938. +        gzprintf(fi," %d ", bg_tiles[y][i]);
  1939.      }
  1940.  
  1941. -  fprintf( fi,")\n");
  1942. -  fprintf(fi,"  (interactive-tm ");
  1943. +  gzprintf( fi,")\n");
  1944. +  gzprintf(fi,"  (interactive-tm ");
  1945.  
  1946.    for(int y = 0; y < 15; ++y)
  1947.      {
  1948.        for(int i = 0; i < width; ++i)
  1949. -        fprintf(fi," %d ", ia_tiles[y][i]);
  1950. +        gzprintf(fi," %d ", ia_tiles[y][i]);
  1951.      }
  1952.  
  1953. -  fprintf( fi,")\n");
  1954. -  fprintf(fi,"  (foreground-tm ");
  1955. +  gzprintf( fi,")\n");
  1956. +  gzprintf(fi,"  (foreground-tm ");
  1957.  
  1958.    for(int y = 0; y < 15; ++y)
  1959.      {
  1960.        for(int i = 0; i < width; ++i)
  1961. -        fprintf(fi," %d ", fg_tiles[y][i]);
  1962. +        gzprintf(fi," %d ", fg_tiles[y][i]);
  1963.      }
  1964.  
  1965. -  fprintf( fi,")\n");
  1966. +  gzprintf( fi,")\n");
  1967.  
  1968. -  fprintf( fi,"(reset-points\n");
  1969. +  gzprintf( fi,"(reset-points\n");
  1970.    for(std::vector<ResetPoint>::iterator i = reset_points.begin();
  1971.        i != reset_points.end(); ++i)
  1972. -    fprintf( fi,"(point (x %d) (y %d))\n",i->x, i->y);
  1973. -  fprintf( fi,")\n");
  1974. +    gzprintf( fi,"(point (x %d) (y %d))\n",i->x, i->y);
  1975. +  gzprintf( fi,")\n");
  1976.  
  1977. -  fprintf( fi,"(objects\n");
  1978. +  gzprintf( fi,"(objects\n");
  1979.  
  1980.    for(std::vector<BadGuyData>::iterator it = badguy_data.begin();
  1981.        it != badguy_data.end();
  1982.        ++it)
  1983. -    fprintf( fi,"(%s (x %d) (y %d) (stay-on-platform %s))\n",
  1984. +    gzprintf( fi,"(%s (x %d) (y %d) (stay-on-platform %s))\n",
  1985.               badguykind_to_string((*it).kind).c_str(),(*it).x,(*it).y,
  1986.               it->stay_on_platform ? "#t" : "#f");
  1987.  
  1988. -  fprintf( fi,")\n");
  1989. +  gzprintf( fi,")\n");
  1990.  
  1991. -  fprintf( fi,")\n");
  1992. +  gzprintf( fi,")\n");
  1993.  
  1994. -  fclose(fi);
  1995. +  gzclose(fi);
  1996.  }
  1997.  
  1998.  
  1999. @@ -708,10 +737,10 @@
  2000.  }
  2001.  
  2002.  void
  2003. -Level::change(float x, float y, int tm, unsigned int c)
  2004. +Level::change(int x, int y, int tm, unsigned int c)
  2005.  {
  2006. -  int yy = ((int)y / 32);
  2007. -  int xx = ((int)x / 32);
  2008. +  int yy = (y / 32);
  2009. +  int xx = (x / 32);
  2010.  
  2011.    if (yy >= 0 && yy < 15 && xx >= 0 && xx <= width)
  2012.      {
  2013. @@ -766,13 +795,13 @@
  2014.  }
  2015.  
  2016.  unsigned int
  2017. -Level::gettileid(float x, float y) const
  2018. +Level::gettileid(int x, int y) const
  2019.  {
  2020.    int xx, yy;
  2021.    unsigned int c;
  2022.  
  2023. -  yy = ((int)y / 32);
  2024. -  xx = ((int)x / 32);
  2025. +  yy = (y / 32);
  2026. +  xx = (x / 32);
  2027.  
  2028.    if (yy >= 0 && yy < 15 && xx >= 0 && xx <= width)
  2029.      c = ia_tiles[yy][xx];
  2030. diff -Naur supertux-0.1.3/src.bak/leveleditor.cpp supertux-0.1.3/src/leveleditor.cpp
  2031. --- supertux-0.1.3/src.bak/leveleditor.cpp  2014-12-06 18:00:56.000000000 -0500
  2032. +++ supertux-0.1.3/src/leveleditor.cpp  2014-12-06 18:04:19.000000000 -0500
  2033. @@ -42,6 +42,7 @@
  2034.  #include "tile.h"
  2035.  #include "resources.h"
  2036.  #include "music_manager.h"
  2037. +#include "fpmath.h"
  2038.  
  2039.  /* definitions to aid development */
  2040.  
  2041. @@ -70,7 +71,7 @@
  2042.  void le_drawlevel();
  2043.  void le_drawinterface();
  2044.  void le_checkevents();
  2045. -void le_change(float x, float y, int tm, unsigned int c);
  2046. +void le_change(fp x, fp y, int tm, unsigned int c);
  2047.  void le_testlevel();
  2048.  void le_showhelp();
  2049.  void le_set_defaults(void);
  2050. @@ -192,19 +193,19 @@
  2051.        if(select_tilegroup_menu_effect.check())
  2052.        {
  2053.          select_tilegroup_menu->set_pos(screen->w - 64 + select_tilegroup_menu_effect.get_left(),
  2054. -                                       66,-0.5,0.5);
  2055. +                                       66,-FP_MENU_RATIO,FP_MENU_RATIO);
  2056.        }
  2057.        else
  2058. -        select_tilegroup_menu->set_pos(screen->w - 64,66,-0.5,0.5);
  2059. +        select_tilegroup_menu->set_pos(screen->w - 64,66,-FP_MENU_RATIO,FP_MENU_RATIO);
  2060.      }
  2061.      else if(Menu::current() == select_objects_menu)
  2062.      {
  2063.        if(select_objects_menu_effect.check())
  2064.        {
  2065. -        select_objects_menu->set_pos(screen->w - 64 + select_objects_menu_effect.get_left(),82,-0.5,0.5);
  2066. +        select_objects_menu->set_pos(screen->w - 64 + select_objects_menu_effect.get_left(),82,-FP_MENU_RATIO,FP_MENU_RATIO);
  2067.        }
  2068.        else
  2069. -        select_objects_menu->set_pos(screen->w - 64,82,-0.5,0.5);
  2070. +        select_objects_menu->set_pos(screen->w - 64,82,-FP_MENU_RATIO,FP_MENU_RATIO);
  2071.      }
  2072.  
  2073.      if(le_world != NULL)
  2074. @@ -518,6 +519,8 @@
  2075.  
  2076.  
  2077.    level_subsets = dsubdirs("/levels", "level1.stl");
  2078. +  if (level_subsets.num_items == 0)
  2079. +    level_subsets = dsubdirs("/levels", "level1.stl.gz");
  2080.    le_level_subset = new LevelSubset;
  2081.  
  2082.    le_world = NULL;
  2083. @@ -611,7 +614,7 @@
  2084.    level_settings_menu->get_item_by_id(MNID_LENGTH).change_input(str);
  2085.    sprintf(str,"%d",le_world->get_level()->time_left);
  2086.    level_settings_menu->get_item_by_id(MNID_TIME).change_input(str);
  2087. -  sprintf(str,"%2.0f",le_world->get_level()->gravity);
  2088. +  sprintf(str,"%2.0f",fp2float(le_world->get_level()->gravity));
  2089.    level_settings_menu->get_item_by_id(MNID_GRAVITY).change_input(str);
  2090.    sprintf(str,"%d",le_world->get_level()->bkgd_speed);
  2091.    level_settings_menu->get_item_by_id(MNID_BGSPEED).change_input(str);
  2092. @@ -663,7 +666,7 @@
  2093.  
  2094.    le_world->get_level()->change_size(atoi(level_settings_menu->get_item_by_id(MNID_LENGTH).input));
  2095.    le_world->get_level()->time_left = atoi(level_settings_menu->get_item_by_id(MNID_TIME).input);
  2096. -  le_world->get_level()->gravity = atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input);
  2097. +  le_world->get_level()->gravity = float2fp(atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input));
  2098.    le_world->get_level()->bkgd_speed = atoi(level_settings_menu->get_item_by_id(MNID_BGSPEED).input);
  2099.    le_world->get_level()->bkgd_top.red = atoi(level_settings_menu->get_item_by_id(MNID_TopRed).input);
  2100.    le_world->get_level()->bkgd_top.green = atoi(level_settings_menu->get_item_by_id(MNID_TopGreen).input);
  2101. @@ -846,10 +849,10 @@
  2102.  
  2103.    if(mouse_select_object && selected_game_object != NULL)
  2104.    {
  2105. -    fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y,selected_game_object->base.width,3,255,0,0,255);
  2106. -    fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y,3,selected_game_object->base.height,255,0,0,255);
  2107. -    fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y+selected_game_object->base.height,selected_game_object->base.width,3,255,0,0,255);
  2108. -    fillrect(selected_game_object->base.x-pos_x+selected_game_object->base.width,selected_game_object->base.y,3,selected_game_object->base.height,255,0,0,255);
  2109. +    fillrect(fp2int(selected_game_object->base.x)-pos_x,fp2int(selected_game_object->base.y),fp2int(selected_game_object->base.width),3,255,0,0,255);
  2110. +    fillrect(fp2int(selected_game_object->base.x)-pos_x,fp2int(selected_game_object->base.y),3,fp2int(selected_game_object->base.height),255,0,0,255);
  2111. +    fillrect(fp2int(selected_game_object->base.x)-pos_x,fp2int(selected_game_object->base.y+selected_game_object->base.height),fp2int(selected_game_object->base.width),3,255,0,0,255);
  2112. +    fillrect(fp2int(selected_game_object->base.x)-pos_x+fp2int(selected_game_object->base.width),fp2int(selected_game_object->base.y),3,fp2int(selected_game_object->base.height),255,0,0,255);
  2113.    }
  2114.  
  2115.    if(le_world != NULL)
  2116. @@ -911,7 +914,7 @@
  2117.    /* Draw the real background */
  2118.    if(le_world->get_level()->bkgd_image[0] != '\0')
  2119.    {
  2120. -    s = (int)((float)pos_x * ((float)le_world->get_level()->bkgd_speed/100.0f)) % screen->w;
  2121. +    s = (pos_x * le_world->get_level()->bkgd_speed / 100) % screen->w;
  2122.      le_world->get_level()->img_bkgd->draw_part(s,0,0,0,
  2123.          le_world->get_level()->img_bkgd->w - s - 32, le_world->get_level()->img_bkgd->h);
  2124.      le_world->get_level()->img_bkgd->draw_part(0,0,screen->w - s - 32 ,0,s,
  2125. @@ -944,21 +947,21 @@
  2126.        else
  2127.          a = 128;
  2128.  
  2129. -      Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->bg_tiles[y][x + (int)(pos_x / 32)],a);
  2130. +      Tile::draw(32*x - (pos_x % 32), y * 32, le_world->get_level()->bg_tiles[y][x + (int)(pos_x / 32)],a);
  2131.  
  2132.        if(active_tm == TM_IA)
  2133.          a = 255;
  2134.        else
  2135.          a = 128;
  2136.  
  2137. -      Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->ia_tiles[y][x + (int)(pos_x / 32)],a);
  2138. +      Tile::draw(32*x - (pos_x % 32), y * 32, le_world->get_level()->ia_tiles[y][x + (int)(pos_x / 32)],a);
  2139.  
  2140.        if(active_tm == TM_FG)
  2141.          a = 255;
  2142.        else
  2143.          a = 128;
  2144.  
  2145. -      Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->fg_tiles[y][x + (int)(pos_x / 32)],a);
  2146. +      Tile::draw(32*x - (pos_x % 32), y * 32, le_world->get_level()->fg_tiles[y][x + (int)(pos_x / 32)],a);
  2147.  
  2148.        /* draw whats inside stuff when cursor is selecting those */
  2149.        /* (draw them all the time - is this the right behaviour?) */
  2150. @@ -973,7 +976,7 @@
  2151.    {
  2152.      /* to support frames: img_bsod_left[(frame / 5) % 4] */
  2153.  
  2154. -    scroll_x = pos_x;
  2155. +    scroll_x = int2fp(pos_x);
  2156.      (*it)->draw();
  2157.    }
  2158.  
  2159. @@ -1040,7 +1043,7 @@
  2160.          le_world->get_level()->badguy_data[i].kind = pbad->kind;
  2161.     le_world->get_level()->badguy_data[i].stay_on_platform = pbad->stay_on_platform;
  2162.     delete (*it);
  2163. -   (*it) = new BadGuy(le_world->get_level()->badguy_data[i].x,le_world->get_level()->badguy_data[i].y,le_world->get_level()->badguy_data[i].kind,le_world->get_level()->badguy_data[i].stay_on_platform);
  2164. +   (*it) = new BadGuy(int2fp(le_world->get_level()->badguy_data[i].x),int2fp(le_world->get_level()->badguy_data[i].y),le_world->get_level()->badguy_data[i].kind,le_world->get_level()->badguy_data[i].stay_on_platform);
  2165.        }
  2166.        loop = false;
  2167.        break;
  2168. @@ -1324,7 +1327,7 @@
  2169.            case BUTTON_CLICKED:
  2170.              Menu::set_current(select_tilegroup_menu);
  2171.              select_tilegroup_menu_effect.start(200);
  2172. -            select_tilegroup_menu->set_pos(screen->w - 64,100,-0.5,0.5);
  2173. +            select_tilegroup_menu->set_pos(screen->w - 64,100,-FP_MENU_RATIO,FP_MENU_RATIO);
  2174.              break;
  2175.            case BUTTON_WHEELUP:
  2176.              if(cur_tilegroup.empty())
  2177. @@ -1371,7 +1374,7 @@
  2178.            case BUTTON_CLICKED:
  2179.              Menu::set_current(select_objects_menu);
  2180.              select_objects_menu_effect.start(200);
  2181. -            select_objects_menu->set_pos(screen->w - 64,100,-0.5,0.5);
  2182. +            select_objects_menu->set_pos(screen->w - 64,100,-FP_MENU_RATIO,FP_MENU_RATIO);
  2183.              break;
  2184.            case BUTTON_WHEELUP:
  2185.              it = objects_map.find(cur_objects);
  2186. @@ -1482,16 +1485,16 @@
  2187.              base_type cursor_base;
  2188.         if(le_current.IsTile())
  2189.         {
  2190. -            cursor_base.x = cursor_x;
  2191. -            cursor_base.y = cursor_y;
  2192. +            cursor_base.x = int2fp(cursor_x);
  2193. +            cursor_base.y = int2fp(cursor_y);
  2194.         }
  2195.         else if(le_current.IsObject())
  2196.         {
  2197. -            cursor_base.x = cursor_x + pos_x;
  2198. -            cursor_base.y = cursor_y + pos_x;     
  2199. +            cursor_base.x = int2fp(cursor_x + pos_x);
  2200. +            cursor_base.y = int2fp(cursor_y + pos_x);
  2201.         }
  2202. -            cursor_base.width = 32;
  2203. -            cursor_base.height = 32;
  2204. +            cursor_base.width = int2fp(32);
  2205. +            cursor_base.height = int2fp(32);
  2206.  
  2207.              for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin(); it != le_world->bad_guys.end(); ++it, ++i)
  2208.                if(rectcollision(cursor_base,(*it)->base))
  2209. @@ -1522,7 +1525,7 @@
  2210.                {
  2211.                  BadGuy* pbadguy = dynamic_cast<BadGuy*>(le_current.obj);
  2212.  
  2213. -                le_world->bad_guys.push_back(new BadGuy(cursor_x+scroll_x, cursor_y,pbadguy->kind,false));
  2214. +                le_world->bad_guys.push_back(new BadGuy(int2fp(cursor_x)+scroll_x, int2fp(cursor_y),pbadguy->kind,false));
  2215.                  le_world->get_level()->badguy_data.push_back(le_world->bad_guys.back());
  2216.                }
  2217.              }
  2218. @@ -1613,7 +1616,7 @@
  2219.    fillrect(x1*32-pos_x, y1*32,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103);
  2220.  }
  2221.  
  2222. -void le_change(float x, float y, int tm, unsigned int c)
  2223. +void le_change(fp x, fp y, int tm, unsigned int c)
  2224.  {
  2225.    if(le_world != NULL)
  2226.    {
  2227. @@ -1626,13 +1629,13 @@
  2228.      switch(le_selection_mode)
  2229.      {
  2230.      case SM_CURSOR:
  2231. -      le_world->get_level()->change(x,y,tm,c);
  2232. +      le_world->get_level()->change(fp2int(x),fp2int(y),tm,c);
  2233.  
  2234.        base_type cursor_base;
  2235.        cursor_base.x = x;
  2236.        cursor_base.y = y;
  2237. -      cursor_base.width = 32;
  2238. -      cursor_base.height = 32;
  2239. +      cursor_base.width = int2fp(32);
  2240. +      cursor_base.height = int2fp(32);
  2241.  
  2242.        /* if there is a bad guy over there, remove it */
  2243.        for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin(); it != le_world->bad_guys.end(); ++it, ++i)
  2244. @@ -1676,8 +1679,8 @@
  2245.        for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin();
  2246.            it != le_world->bad_guys.end(); /* will be at end of loop */)
  2247.        {
  2248. -        if((*it)->base.x/32 >= x1 && (*it)->base.x/32 <= x2
  2249. -            && (*it)->base.y/32 >= y1 && (*it)->base.y/32 <= y2)
  2250. +        if((*it)->base.x/32 >= int2fp(x1) && (*it)->base.x/32 <= int2fp(x2)
  2251. +            && (*it)->base.y/32 >= int2fp(y1) && (*it)->base.y/32 <= int2fp(y2))
  2252.          {
  2253.            delete (*it);
  2254.            it = le_world->bad_guys.erase(it);
  2255. diff -Naur supertux-0.1.3/src.bak/level.h supertux-0.1.3/src/level.h
  2256. --- supertux-0.1.3/src.bak/level.h  2014-12-06 18:00:56.000000000 -0500
  2257. +++ supertux-0.1.3/src/level.h  2014-12-06 18:04:19.000000000 -0500
  2258. @@ -26,6 +26,7 @@
  2259.  #include "badguy.h"
  2260.  #include "lispreader.h"
  2261.  #include "musicref.h"
  2262. +#include "fpmath.h"
  2263.  
  2264.  class Tile;
  2265.  
  2266. @@ -88,9 +89,9 @@
  2267.    int bkgd_speed;
  2268.    int start_pos_x;
  2269.    int start_pos_y;
  2270. -  float gravity;
  2271. +  fp gravity;
  2272.    bool back_scrolling;
  2273. -  float hor_autoscroll_speed;
  2274. +  fp hor_autoscroll_speed;
  2275.  
  2276.    std::vector<BadGuyData> badguy_data;
  2277.  
  2278. @@ -126,13 +127,13 @@
  2279.    void save(const std::string& subset, int level);
  2280.  
  2281.    /** Edit a piece of the map! */
  2282. -  void change(float x, float y, int tm, unsigned int c);
  2283. +  void change(int x, int y, int tm, unsigned int c);
  2284.  
  2285.    /** Resize the level to a new width */
  2286.    void change_size (int new_width);
  2287.  
  2288.    /** Return the id of the tile at position x/y */
  2289. -  unsigned int gettileid(float x, float y) const;
  2290. +  unsigned int gettileid(int x, int y) const;
  2291.    /** returns the id of the tile at position x,y
  2292.     * (these are logical and not pixel coordinates)
  2293.     */
  2294. diff -Naur supertux-0.1.3/src.bak/lispreader.cpp supertux-0.1.3/src/lispreader.cpp
  2295. --- supertux-0.1.3/src.bak/lispreader.cpp   2014-12-06 18:00:56.000000000 -0500
  2296. +++ supertux-0.1.3/src/lispreader.cpp   2014-12-06 18:04:19.000000000 -0500
  2297. @@ -92,6 +92,9 @@
  2298.  
  2299.      case LISP_STREAM_ANY:
  2300.        return stream->v.any.next_char(stream->v.any.data);
  2301. +
  2302. +    case LISP_STREAM_GZFILE :
  2303. +      return gzgetc(stream->v.gzfile);
  2304.      }
  2305.    assert(0);
  2306.    return EOF;
  2307. @@ -114,6 +117,10 @@
  2308.        stream->v.any.unget_char(c, stream->v.any.data);
  2309.        break;
  2310.  
  2311. +    case LISP_STREAM_GZFILE :
  2312. +      gzungetc(c, stream->v.gzfile);
  2313. +      break;
  2314. +
  2315.      default :
  2316.        assert(0);
  2317.      }
  2318. @@ -315,6 +322,15 @@
  2319.    return stream;
  2320.  }
  2321.  
  2322. +lisp_stream_t* lisp_stream_init_gzfile (lisp_stream_t *stream, gzFile file)
  2323. +{
  2324. +  //return lisp_stream_init_any (stream, file, gzgetc, mygzungetc);
  2325. +  stream->type = LISP_STREAM_GZFILE;
  2326. +  stream->v.gzfile = file;
  2327. +
  2328. +  return stream;
  2329. +}
  2330. +
  2331.  lisp_object_t*
  2332.  lisp_make_integer (int value)
  2333.  {
  2334. @@ -1297,12 +1313,6 @@
  2335.    gzungetc(c, file);
  2336.  }
  2337.  
  2338. -lisp_stream_t* lisp_stream_init_gzfile (lisp_stream_t *stream, gzFile file)
  2339. -{
  2340. -  return lisp_stream_init_any (stream, file, gzgetc, mygzungetc);
  2341. -}
  2342. -#endif
  2343. -
  2344.  lisp_object_t* lisp_read_from_gzfile(const char* filename)
  2345.  {
  2346.    bool done = false;
  2347. @@ -1346,6 +1356,7 @@
  2348.  
  2349.    return root_obj;
  2350.  }
  2351. +#endif
  2352.  
  2353.  bool has_suffix(const char* data, const char* suffix)
  2354.  {
  2355. @@ -1367,25 +1378,31 @@
  2356.  lisp_object_t* lisp_read_from_file(const std::string& filename)
  2357.  {
  2358.    lisp_stream_t stream;
  2359. +  char fname[1024];
  2360. +
  2361. +  strcpy(fname, filename.c_str());
  2362. +  if(!faccessible(fname)) {
  2363. +   strcat(fname, ".gz");
  2364. +  }
  2365.  
  2366. -  if (has_suffix(filename.c_str(), ".gz"))
  2367. +/*  if (has_suffix(filename.c_str(), ".gz"))
  2368.      {
  2369.        return lisp_read_from_gzfile(filename.c_str());
  2370.      }
  2371.    else
  2372. -    {
  2373. +    { */
  2374.        lisp_object_t* obj = 0;
  2375. -      FILE* in = fopen(filename.c_str(), "r");
  2376. +      gzFile in = gzopen(fname, "r");
  2377.  
  2378.        if (in)
  2379.          {
  2380. -          lisp_stream_init_file(&stream, in);
  2381. +          lisp_stream_init_gzfile(&stream, in);
  2382.            obj = lisp_read(&stream);
  2383. -          fclose(in);
  2384. +          gzclose(in);
  2385.          }
  2386.  
  2387.        return obj;
  2388. -    }
  2389. +/*    } */
  2390.  }
  2391.  
  2392.  // EOF //
  2393. diff -Naur supertux-0.1.3/src.bak/lispreader.h supertux-0.1.3/src/lispreader.h
  2394. --- supertux-0.1.3/src.bak/lispreader.h 2014-12-06 18:00:56.000000000 -0500
  2395. +++ supertux-0.1.3/src/lispreader.h 2014-12-06 18:04:19.000000000 -0500
  2396. @@ -32,6 +32,7 @@
  2397.  #define LISP_STREAM_FILE       1
  2398.  #define LISP_STREAM_STRING     2
  2399.  #define LISP_STREAM_ANY        3
  2400. +#define LISP_STREAM_GZFILE     4
  2401.  
  2402.  #define LISP_TYPE_INTERNAL      -3
  2403.  #define LISP_TYPE_PARSE_ERROR   -2
  2404. @@ -62,6 +63,7 @@
  2405.      union
  2406.        {
  2407.          FILE *file;
  2408. +        gzFile gzfile;
  2409.          struct
  2410.            {
  2411.              char *buf;
  2412. diff -Naur supertux-0.1.3/src.bak/Makefile supertux-0.1.3/src/Makefile
  2413. --- supertux-0.1.3/src.bak/Makefile 2014-12-06 18:00:56.000000000 -0500
  2414. +++ supertux-0.1.3/src/Makefile 2014-12-07 11:39:50.000000000 -0500
  2415. @@ -46,6 +46,7 @@
  2416.  AWK = gawk
  2417.  CC = gcc
  2418.  CCDEPMODE = depmode=gcc3
  2419. +#CFLAGS = -g -O2 -I/usr/local/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT
  2420.  CFLAGS = -g -O2 -I/usr/local/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -pthread
  2421.  CPP = gcc -E
  2422.  CPPFLAGS =
  2423. @@ -217,7 +218,9 @@
  2424.  music_manager.cpp \
  2425.  music_manager.h \
  2426.  musicref.cpp \
  2427. -musicref.h
  2428. +musicref.h \
  2429. +fpmath.h \
  2430. +fpmath.cpp
  2431.  
  2432.  subdir = src
  2433.  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
  2434. @@ -238,7 +241,7 @@
  2435.     type.$(OBJEXT) world.$(OBJEXT) worldmap.$(OBJEXT) \
  2436.     tile.$(OBJEXT) mousecursor.$(OBJEXT) resources.$(OBJEXT) \
  2437.     gameobjs.$(OBJEXT) sprite.$(OBJEXT) sprite_manager.$(OBJEXT) \
  2438. -   music_manager.$(OBJEXT) musicref.$(OBJEXT)
  2439. +   music_manager.$(OBJEXT) musicref.$(OBJEXT) fpmath.$(OBJEXT)
  2440.  supertux_OBJECTS = $(am_supertux_OBJECTS)
  2441.  supertux_LDADD = $(LDADD)
  2442.  supertux_DEPENDENCIES =
  2443. @@ -249,10 +252,11 @@
  2444.  am__depfiles_maybe = depfiles
  2445.  DEP_FILES = ./$(DEPDIR)/badguy.Po ./$(DEPDIR)/bitmask.Po \
  2446.     ./$(DEPDIR)/button.Po ./$(DEPDIR)/collision.Po \
  2447. -   ./$(DEPDIR)/configfile.Po ./$(DEPDIR)/gameloop.Po \
  2448. -   ./$(DEPDIR)/gameobjs.Po ./$(DEPDIR)/globals.Po \
  2449. -   ./$(DEPDIR)/high_scores.Po ./$(DEPDIR)/intro.Po \
  2450. -   ./$(DEPDIR)/level.Po ./$(DEPDIR)/leveleditor.Po \
  2451. +   ./$(DEPDIR)/configfile.Po ./$(DEPDIR)/fpmath.Po \
  2452. +   ./$(DEPDIR)/gameloop.Po ./$(DEPDIR)/gameobjs.Po \
  2453. +   ./$(DEPDIR)/globals.Po ./$(DEPDIR)/high_scores.Po \
  2454. +   ./$(DEPDIR)/intro.Po ./$(DEPDIR)/level.Po \
  2455. +   ./$(DEPDIR)/leveleditor.Po \
  2456.     ./$(DEPDIR)/lispreader.Po ./$(DEPDIR)/menu.Po \
  2457.     ./$(DEPDIR)/mousecursor.Po \
  2458.     ./$(DEPDIR)/music_manager.Po \
  2459. @@ -329,6 +333,7 @@
  2460.  include ./$(DEPDIR)/button.Po
  2461.  include ./$(DEPDIR)/collision.Po
  2462.  include ./$(DEPDIR)/configfile.Po
  2463. +include ./$(DEPDIR)/fpmath.Po
  2464.  include ./$(DEPDIR)/gameloop.Po
  2465.  include ./$(DEPDIR)/gameobjs.Po
  2466.  include ./$(DEPDIR)/globals.Po
  2467. diff -Naur supertux-0.1.3/src.bak/Makefile.am supertux-0.1.3/src/Makefile.am
  2468. --- supertux-0.1.3/src.bak/Makefile.am  2014-12-06 18:00:56.000000000 -0500
  2469. +++ supertux-0.1.3/src/Makefile.am  2014-12-06 18:04:19.000000000 -0500
  2470. @@ -74,7 +74,9 @@
  2471.  music_manager.cpp \
  2472.  music_manager.h \
  2473.  musicref.cpp \
  2474. -musicref.h
  2475. +musicref.h \
  2476. +fpmath.h \
  2477. +fpmath.cpp
  2478.  
  2479.  # EOF #
  2480.  
  2481. diff -Naur supertux-0.1.3/src.bak/Makefile.in supertux-0.1.3/src/Makefile.in
  2482. --- supertux-0.1.3/src.bak/Makefile.in  2014-12-06 18:00:56.000000000 -0500
  2483. +++ supertux-0.1.3/src/Makefile.in  2014-12-07 10:52:16.000000000 -0500
  2484. @@ -215,7 +215,9 @@
  2485.  music_manager.cpp \
  2486.  music_manager.h \
  2487.  musicref.cpp \
  2488. -musicref.h
  2489. +musicref.h \
  2490. +fpmath.h \
  2491. +fpmath.cpp
  2492.  
  2493.  subdir = src
  2494.  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
  2495. @@ -236,7 +238,7 @@
  2496.     type.$(OBJEXT) world.$(OBJEXT) worldmap.$(OBJEXT) \
  2497.     tile.$(OBJEXT) mousecursor.$(OBJEXT) resources.$(OBJEXT) \
  2498.     gameobjs.$(OBJEXT) sprite.$(OBJEXT) sprite_manager.$(OBJEXT) \
  2499. -   music_manager.$(OBJEXT) musicref.$(OBJEXT)
  2500. +   music_manager.$(OBJEXT) musicref.$(OBJEXT) fpmath.$(OBJEXT)
  2501.  supertux_OBJECTS = $(am_supertux_OBJECTS)
  2502.  supertux_LDADD = $(LDADD)
  2503.  supertux_DEPENDENCIES =
  2504. @@ -247,10 +249,11 @@
  2505.  am__depfiles_maybe = depfiles
  2506.  @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/badguy.Po ./$(DEPDIR)/bitmask.Po \
  2507.  @AMDEP_TRUE@   ./$(DEPDIR)/button.Po ./$(DEPDIR)/collision.Po \
  2508. -@AMDEP_TRUE@   ./$(DEPDIR)/configfile.Po ./$(DEPDIR)/gameloop.Po \
  2509. -@AMDEP_TRUE@   ./$(DEPDIR)/gameobjs.Po ./$(DEPDIR)/globals.Po \
  2510. -@AMDEP_TRUE@   ./$(DEPDIR)/high_scores.Po ./$(DEPDIR)/intro.Po \
  2511. -@AMDEP_TRUE@   ./$(DEPDIR)/level.Po ./$(DEPDIR)/leveleditor.Po \
  2512. +@AMDEP_TRUE@   ./$(DEPDIR)/configfile.Po ./$(DEPDIR)/fpmath.Po \
  2513. +@AMDEP_TRUE@   ./$(DEPDIR)/gameloop.Po ./$(DEPDIR)/gameobjs.Po \
  2514. +@AMDEP_TRUE@   ./$(DEPDIR)/globals.Po ./$(DEPDIR)/high_scores.Po \
  2515. +@AMDEP_TRUE@   ./$(DEPDIR)/intro.Po ./$(DEPDIR)/level.Po \
  2516. +@AMDEP_TRUE@   ./$(DEPDIR)/leveleditor.Po \
  2517.  @AMDEP_TRUE@   ./$(DEPDIR)/lispreader.Po ./$(DEPDIR)/menu.Po \
  2518.  @AMDEP_TRUE@   ./$(DEPDIR)/mousecursor.Po \
  2519.  @AMDEP_TRUE@   ./$(DEPDIR)/music_manager.Po \
  2520. @@ -327,6 +330,7 @@
  2521.  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/button.Po@am__quote@
  2522.  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision.Po@am__quote@
  2523.  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/configfile.Po@am__quote@
  2524. +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpmath.Po@am__quote@
  2525.  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gameloop.Po@am__quote@
  2526.  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gameobjs.Po@am__quote@
  2527.  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Po@am__quote@
  2528. diff -Naur supertux-0.1.3/src.bak/menu.cpp supertux-0.1.3/src/menu.cpp
  2529. --- supertux-0.1.3/src.bak/menu.cpp 2014-12-06 18:00:56.000000000 -0500
  2530. +++ supertux-0.1.3/src/menu.cpp 2014-12-06 18:04:19.000000000 -0500
  2531. @@ -38,6 +38,7 @@
  2532.  #include "leveleditor.h"
  2533.  #include "timer.h"
  2534.  #include "high_scores.h"
  2535. +#include "fpmath.h"
  2536.  
  2537.  #define FLICK_CURSOR_TIME 500
  2538.  
  2539. @@ -328,10 +329,10 @@
  2540.    effect.init(false);
  2541.  }
  2542.  
  2543. -void Menu::set_pos(int x, int y, float rw, float rh)
  2544. +void Menu::set_pos(int x, int y, fp rw, fp rh)
  2545.  {
  2546. -  pos_x = x + (int)((float)get_width() * rw);
  2547. -  pos_y = y + (int)((float)get_height() * rh);
  2548. +  pos_x = x + fp2int(get_width() * rw);
  2549. +  pos_y = y + fp2int(get_height() * rh);
  2550.  }
  2551.  
  2552.  void
  2553. diff -Naur supertux-0.1.3/src.bak/menu.h supertux-0.1.3/src/menu.h
  2554. --- supertux-0.1.3/src.bak/menu.h   2014-12-06 18:00:56.000000000 -0500
  2555. +++ supertux-0.1.3/src/menu.h   2014-12-06 18:04:19.000000000 -0500
  2556. @@ -26,6 +26,7 @@
  2557.  #include "timer.h"
  2558.  #include "type.h"
  2559.  #include "mousecursor.h"
  2560. +#include "fpmath.h"
  2561.  
  2562.  /* IDs for menus */
  2563.  
  2564. @@ -211,7 +212,7 @@
  2565.  
  2566.    void draw   ();
  2567.    void draw_item(int index, int menu_width, int menu_height);
  2568. -  void set_pos(int x, int y, float rw = 0, float rh = 0);
  2569. +  void set_pos(int x, int y, fp rw = 0, fp rh = 0);
  2570.  
  2571.    /** translate a SDL_Event into a menu_action */
  2572.    void event(SDL_Event& event);
  2573. diff -Naur supertux-0.1.3/src.bak/particlesystem.cpp supertux-0.1.3/src/particlesystem.cpp
  2574. --- supertux-0.1.3/src.bak/particlesystem.cpp   2014-12-06 18:00:56.000000000 -0500
  2575. +++ supertux-0.1.3/src/particlesystem.cpp   2014-12-07 11:00:44.000000000 -0500
  2576. @@ -26,12 +26,13 @@
  2577.  #include "world.h"
  2578.  #include "level.h"
  2579.  #include "scene.h"
  2580. +#include "fpmath.h"
  2581.  
  2582.  ParticleSystem::ParticleSystem()
  2583.  {
  2584.  #ifndef RES320X240
  2585. -    virtual_width = screen->w;
  2586. -    virtual_height = screen->h;
  2587. +  virtual_width = int2fp(screen->w);
  2588. +  virtual_height = int2fp(screen->h);
  2589.  #else
  2590.      virtual_width = 640;
  2591.      virtual_height = 480;
  2592. @@ -46,8 +47,11 @@
  2593.      }
  2594.  }
  2595.  
  2596. -void ParticleSystem::draw(float scrollx, float scrolly, int layer)
  2597. +void ParticleSystem::draw(fp scrollx, fp scrolly, int layer)
  2598.  {
  2599. +   int v_width = fp2int(virtual_width);
  2600. +   int v_height = fp2int(virtual_height);
  2601. +
  2602.      std::vector<Particle*>::iterator i;
  2603.      for(i = particles.begin(); i != particles.end(); ++i) {
  2604.          Particle* particle = *i;
  2605. @@ -55,12 +59,12 @@
  2606.              continue;
  2607.          
  2608.          // remap x,y coordinates onto screencoordinates
  2609. -        float x = fmodf(particle->x - scrollx, virtual_width);
  2610. -        if(x < 0) x += virtual_width;
  2611. -        float y = fmodf(particle->y - scrolly, virtual_height);
  2612. -        if(y < 0) y += virtual_height;
  2613. -        float xmax = fmodf(x + particle->texture->w, virtual_width);
  2614. -        float ymax = fmodf(y + particle->texture->h, virtual_height);
  2615. +        int x = fp2int((particle->x - scrollx) % (virtual_width));
  2616. +        if(x < 0) x += v_width;
  2617. +        int y = fp2int((particle->y - scrolly) % (virtual_height));
  2618. +        if(y < 0) y += v_height;
  2619. +        int xmax = (x + particle->texture->w) % (v_width);
  2620. +        int ymax = (y + particle->texture->h) % (v_height);
  2621.  
  2622.          // particle on screen
  2623.  #ifndef RES320X240
  2624. @@ -69,16 +73,16 @@
  2625.          if(y >= screen->h && ymax >= screen->h)
  2626.              continue;
  2627.  
  2628. -        if(x > screen->w) x -= virtual_width;
  2629. -        if(y > screen->h) y -= virtual_height;
  2630. +        if(x > screen->w) x -= v_width;
  2631. +        if(y > screen->h) y -= v_height;
  2632.  #else
  2633.          if(x >= 640 && xmax >= 640)
  2634.              continue;
  2635.          if(y >= 480 && ymax >= 480)
  2636.              continue;
  2637.  
  2638. -        if(x > 640) x -= virtual_width;
  2639. -        if(y > 480) y -= virtual_height;
  2640. +        if(x > 640) x -= v_width;
  2641. +        if(y > 480) y -= v_height;
  2642.  #endif
  2643.          
  2644.          particle->texture->draw(x, y);
  2645. @@ -92,27 +96,27 @@
  2646.      snowimages[2] = new Surface(datadir+"/images/shared/snow2.png", USE_ALPHA);
  2647.  
  2648.  #ifndef RES320X240
  2649. -    virtual_width = screen->w * 2;
  2650. +    virtual_width = int2fp(screen->w * 2);
  2651.  #else
  2652. -    virtual_width = 640 * 2;
  2653. +    virtual_width = int2fp(640 * 2);
  2654.  #endif
  2655.      // create some random snowflakes
  2656. -    size_t snowflakecount = size_t(virtual_width/10.0);
  2657. +    size_t snowflakecount = size_t(fp2int(virtual_width/10));
  2658.      for(size_t i=0; i<snowflakecount; ++i) {
  2659.          SnowParticle* particle = new SnowParticle;
  2660. -        particle->x = rand() % int(virtual_width);
  2661. +        particle->x = int2fp(rand() % fp2int(virtual_width));
  2662.  #ifndef RES320X240
  2663. -        particle->y = rand() % screen->h;
  2664. +        particle->y = int2fp(rand() % screen->h);
  2665.  #else
  2666. -        particle->y = rand() % 480;
  2667. +        particle->y = int2fp(rand() % 480);
  2668.  #endif
  2669.          particle->layer = i % 2;
  2670.          int snowsize = rand() % 3;
  2671.          particle->texture = snowimages[snowsize];
  2672.          do {
  2673. -            particle->speed = snowsize/60.0 + (float(rand()%10)/300.0);
  2674. -        } while(particle->speed < 0.01);
  2675. -        particle->speed *= World::current()->get_level()->gravity;
  2676. +            particle->speed = int2fp(snowsize)/60 + int2fp(rand()%10) / 300;
  2677. +        } while(particle->speed < FP_MIN_PARTICLE_SPEED);
  2678. +        particle->speed = fpmul(particle->speed, World::current()->get_level()->gravity);
  2679.  
  2680.          particles.push_back(particle);
  2681.      }
  2682. @@ -124,19 +128,19 @@
  2683.      delete snowimages[i];
  2684.  }
  2685.  
  2686. -void SnowParticleSystem::simulate(float elapsed_time)
  2687. +void SnowParticleSystem::simulate(fp elapsed_time)
  2688.  {
  2689.      std::vector<Particle*>::iterator i;
  2690.      for(i = particles.begin(); i != particles.end(); ++i) {
  2691.          SnowParticle* particle = (SnowParticle*) *i;
  2692. -        particle->y += particle->speed * elapsed_time;
  2693. +        particle->y += fpmul(particle->speed, elapsed_time);
  2694.  #ifndef RES320X240
  2695. -        if(particle->y > screen->h) {
  2696. +        if(particle->y > virtual_height) {
  2697.  #else
  2698.          if(particle->y > 480) {
  2699.  #endif
  2700. -            particle->y = fmodf(particle->y , virtual_height);
  2701. -            particle->x = rand() % int(virtual_width);
  2702. +            particle->y = particle->y % virtual_height;
  2703. +            particle->x = rand() % virtual_width;
  2704.          }
  2705.      }
  2706.  }
  2707. @@ -145,16 +149,16 @@
  2708.  {
  2709.      cloudimage = new Surface(datadir + "/images/shared/cloud.png", USE_ALPHA);
  2710.  
  2711. -    virtual_width = 2000.0;
  2712. +    virtual_width = int2fp(2000);
  2713.  
  2714.      // create some random clouds
  2715.      for(size_t i=0; i<15; ++i) {
  2716.          CloudParticle* particle = new CloudParticle;
  2717. -        particle->x = rand() % int(virtual_width);
  2718. -        particle->y = rand() % int(virtual_height);
  2719. +        particle->x = rand() % virtual_width;
  2720. +        particle->y = rand() % virtual_height;
  2721.          particle->layer = 0;
  2722.          particle->texture = cloudimage;
  2723. -        particle->speed = -float(250 + rand() % 200) / 1000.0;
  2724. +        particle->speed = -int2fp(250 + rand() % 200) / 1000;
  2725.  
  2726.          particles.push_back(particle);
  2727.      }
  2728. @@ -165,11 +169,11 @@
  2729.    delete cloudimage;
  2730.  }
  2731.  
  2732. -void CloudParticleSystem::simulate(float elapsed_time)
  2733. +void CloudParticleSystem::simulate(fp elapsed_time)
  2734.  {
  2735.      std::vector<Particle*>::iterator i;
  2736.      for(i = particles.begin(); i != particles.end(); ++i) {
  2737.          CloudParticle* particle = (CloudParticle*) *i;
  2738. -        particle->x += particle->speed * elapsed_time;
  2739. +        particle->x += fpmul(particle->speed, elapsed_time);
  2740.      }
  2741.  }
  2742. diff -Naur supertux-0.1.3/src.bak/particlesystem.h supertux-0.1.3/src/particlesystem.h
  2743. --- supertux-0.1.3/src.bak/particlesystem.h 2014-12-06 18:00:56.000000000 -0500
  2744. +++ supertux-0.1.3/src/particlesystem.h 2014-12-06 18:04:19.000000000 -0500
  2745. @@ -22,6 +22,7 @@
  2746.  
  2747.  #include <vector>
  2748.  #include "texture.h"
  2749. +#include "fpmath.h"
  2750.  
  2751.  /**
  2752.   * This is the base class for particle systems. It is responsible for storing a
  2753. @@ -44,9 +45,9 @@
  2754.      ParticleSystem();
  2755.      virtual ~ParticleSystem();
  2756.      
  2757. -    void draw(float scrollx, float scrolly, int layer);
  2758. +    void draw(fp scrollx, fp scrolly, int layer);
  2759.  
  2760. -    virtual void simulate(float elapsed_time) = 0;
  2761. +    virtual void simulate(fp elapsed_time) = 0;
  2762.  
  2763.  protected:
  2764.      class Particle
  2765. @@ -55,13 +56,13 @@
  2766.          virtual ~Particle()
  2767.          { }
  2768.  
  2769. -        float x, y;
  2770. +        fp x, y;
  2771.          int layer;
  2772.          Surface* texture;
  2773.      };
  2774.      
  2775.      std::vector<Particle*> particles;
  2776. -    float virtual_width, virtual_height;
  2777. +    fp virtual_width, virtual_height;
  2778.  };
  2779.  
  2780.  class SnowParticleSystem : public ParticleSystem
  2781. @@ -70,13 +71,13 @@
  2782.      SnowParticleSystem();
  2783.      virtual ~SnowParticleSystem();
  2784.  
  2785. -    virtual void simulate(float elapsed_time);
  2786. +    virtual void simulate(fp elapsed_time);
  2787.      
  2788.  private:
  2789.      class SnowParticle : public Particle
  2790.      {
  2791.      public:
  2792. -        float speed;
  2793. +        fp speed;
  2794.      };
  2795.      
  2796.      Surface* snowimages[3];
  2797. @@ -88,13 +89,13 @@
  2798.      CloudParticleSystem();
  2799.      virtual ~CloudParticleSystem();
  2800.  
  2801. -    virtual void simulate(float elapsed_time);
  2802. +    virtual void simulate(fp elapsed_time);
  2803.      
  2804.  private:
  2805.      class CloudParticle : public Particle
  2806.      {
  2807.      public:
  2808. -        float speed;
  2809. +        fp speed;
  2810.      };
  2811.      
  2812.      Surface* cloudimage;
  2813. diff -Naur supertux-0.1.3/src.bak/physic.cpp supertux-0.1.3/src/physic.cpp
  2814. --- supertux-0.1.3/src.bak/physic.cpp   2014-12-06 18:00:56.000000000 -0500
  2815. +++ supertux-0.1.3/src/physic.cpp   2014-12-06 18:04:19.000000000 -0500
  2816. @@ -26,6 +26,7 @@
  2817.  #include "timer.h"
  2818.  #include "world.h"
  2819.  #include "level.h"
  2820. +#include "fpmath.h"
  2821.  
  2822.  Physic::Physic()
  2823.      : ax(0), ay(0), vx(0), vy(0), gravity_enabled(true)
  2824. @@ -44,19 +45,19 @@
  2825.  }
  2826.  
  2827.  void
  2828. -Physic::set_velocity_x(float nvx)
  2829. +Physic::set_velocity_x(fp nvx)
  2830.  {
  2831.    vx = nvx;
  2832.  }
  2833.  
  2834.  void
  2835. -Physic::set_velocity_y(float nvy)
  2836. +Physic::set_velocity_y(fp nvy)
  2837.  {
  2838.    vy = -nvy;
  2839.  }
  2840.  
  2841.  void
  2842. -Physic::set_velocity(float nvx, float nvy)
  2843. +Physic::set_velocity(fp nvx, fp nvy)
  2844.  {
  2845.    vx = nvx;
  2846.    vy = -nvy;
  2847. @@ -72,44 +73,44 @@
  2848.  vy = -vy;
  2849.  }
  2850.  
  2851. -float
  2852. +fp
  2853.  Physic::get_velocity_x()
  2854.  {
  2855.      return vx;
  2856.  }
  2857.  
  2858. -float
  2859. +fp
  2860.  Physic::get_velocity_y()
  2861.  {
  2862.      return -vy;
  2863.  }
  2864.  
  2865.  void
  2866. -Physic::set_acceleration_x(float nax)
  2867. +Physic::set_acceleration_x(fp nax)
  2868.  {
  2869.    ax = nax;
  2870.  }
  2871.  
  2872.  void
  2873. -Physic::set_acceleration_y(float nay)
  2874. +Physic::set_acceleration_y(fp nay)
  2875.  {
  2876.    ay = -nay;
  2877.  }
  2878.  
  2879.  void
  2880. -Physic::set_acceleration(float nax, float nay)
  2881. +Physic::set_acceleration(fp nax, fp nay)
  2882.  {
  2883.      ax = nax;
  2884.      ay = -nay;
  2885.  }
  2886.  
  2887. -float
  2888. +fp
  2889.  Physic::get_acceleration_x()
  2890.  {
  2891.      return ax;
  2892.  }
  2893.  
  2894. -float
  2895. +fp
  2896.  Physic::get_acceleration_y()
  2897.  {
  2898.      return -ay;
  2899. @@ -122,17 +123,19 @@
  2900.  }
  2901.  
  2902.  void
  2903. -Physic::apply(float frame_ratio, float &x, float &y)
  2904. +Physic::apply(fp frame_ratio, fp &x, fp &y)
  2905.  {
  2906. -  float gravity = World::current()->get_level()->gravity;
  2907. -  float grav;
  2908. +  fp gravity = World::current()->get_level()->gravity;
  2909. +  fp grav;
  2910.    if(gravity_enabled)
  2911. -    grav = gravity / 100.0;
  2912. +    grav = gravity / 100;
  2913.    else
  2914.      grav = 0;
  2915.  
  2916. -  x += vx * frame_ratio + ax * frame_ratio * frame_ratio;
  2917. -  y += vy * frame_ratio + (ay + grav) * frame_ratio * frame_ratio;
  2918. -  vx += ax * frame_ratio;
  2919. -  vy += (ay + grav) * frame_ratio;
  2920. +  fp frame_ratio_2 = fpmul(frame_ratio, frame_ratio);
  2921. +
  2922. +  x += fpmul(vx, frame_ratio) + fpmul(ax, frame_ratio_2);
  2923. +  y += fpmul(vy, frame_ratio) + fpmul((ay + grav), frame_ratio_2);
  2924. +  vx += fpmul(ax, frame_ratio);
  2925. +  vy += fpmul((ay + grav), frame_ratio);
  2926.  }
  2927. diff -Naur supertux-0.1.3/src.bak/physic.h supertux-0.1.3/src/physic.h
  2928. --- supertux-0.1.3/src.bak/physic.h 2014-12-06 18:00:56.000000000 -0500
  2929. +++ supertux-0.1.3/src/physic.h 2014-12-06 18:04:19.000000000 -0500
  2930. @@ -21,6 +21,8 @@
  2931.  #ifndef SUPERTUX_PHYSIC_H
  2932.  #define SUPERTUX_PHYSIC_H
  2933.  
  2934. +#include "fpmath.h"
  2935. +
  2936.  /** This is a very simplistic physics engine handling accelerated and constant
  2937.    * movement along with gravity.
  2938.    */
  2939. @@ -34,40 +36,40 @@
  2940.      void reset();
  2941.  
  2942.      /** sets velocity to a fixed value */
  2943. -    void set_velocity(float vx, float vy);
  2944. +    void set_velocity(fp vx, fp vy);
  2945.  
  2946. -    void set_velocity_x(float vx);
  2947. -    void set_velocity_y(float vy);
  2948. +    void set_velocity_x(fp vx);
  2949. +    void set_velocity_y(fp vy);
  2950.  
  2951.      /** velocities invertion */
  2952.      void inverse_velocity_x();
  2953.      void inverse_velocity_y();
  2954.  
  2955. -    float get_velocity_x();
  2956. -    float get_velocity_y();
  2957. +    fp get_velocity_x();
  2958. +    fp get_velocity_y();
  2959.      
  2960.      /** sets acceleration applied to the object. (Note that gravity is
  2961.       * eventually added to the vertical acceleration)
  2962.       */
  2963. -    void set_acceleration(float ax, float ay);
  2964. +    void set_acceleration(fp ax, fp ay);
  2965.  
  2966. -    void set_acceleration_x(float ax);
  2967. -    void set_acceleration_y(float ay);
  2968. +    void set_acceleration_x(fp ax);
  2969. +    void set_acceleration_y(fp ay);
  2970.  
  2971. -    float get_acceleration_x();
  2972. -    float get_acceleration_y();
  2973. +    fp get_acceleration_x();
  2974. +    fp get_acceleration_y();
  2975.  
  2976.      /** enables or disables handling of gravity */
  2977.      void enable_gravity(bool gravity_enabled);
  2978.  
  2979.      /** applies the physical simulation to given x and y coordinates */
  2980. -    void apply(float frame_ratio, float &x, float &y);
  2981. +    void apply(fp frame_ratio, fp &x, fp &y);
  2982.  
  2983.  private:
  2984.      /// horizontal and vertical acceleration
  2985. -    float ax, ay;
  2986. +    fp ax, ay;
  2987.      /// horizontal and vertical velocity
  2988. -    float vx, vy;
  2989. +    fp vx, vy;
  2990.      /// should we respect gravity in out calculations?
  2991.      bool gravity_enabled;
  2992.  };
  2993. diff -Naur supertux-0.1.3/src.bak/player.cpp supertux-0.1.3/src/player.cpp
  2994. --- supertux-0.1.3/src.bak/player.cpp   2014-12-06 18:00:56.000000000 -0500
  2995. +++ supertux-0.1.3/src/player.cpp   2014-12-07 09:37:41.000000000 -0500
  2996. @@ -26,6 +26,7 @@
  2997.  #include "tile.h"
  2998.  #include "sprite.h"
  2999.  #include "screen.h"
  3000. +#include "fpmath.h"
  3001.  
  3002.  #define AUTOSCROLL_DEAD_INTERVAL 300
  3003.  
  3004. @@ -68,14 +69,14 @@
  3005.  
  3006.    holding_something = false;
  3007.  
  3008. -  base.width = 32;
  3009. -  base.height = 32;
  3010. +  base.width = int2fp(32);
  3011. +  base.height = int2fp(32);
  3012.  
  3013.    size = SMALL;
  3014.    got_coffee = false;
  3015.  
  3016. -  base.x = plevel->start_pos_x;
  3017. -  base.y = plevel->start_pos_y;
  3018. +  base.x = int2fp(plevel->start_pos_x);
  3019. +  base.y = int2fp(plevel->start_pos_y);
  3020.    base.xm = 0;
  3021.    base.ym = 0;
  3022.    previous_base = old_base = base;
  3023. @@ -138,8 +139,8 @@
  3024.  void
  3025.  Player::level_begin()
  3026.  {
  3027. -  base.x  = 100;
  3028. -  base.y  = 170;
  3029. +  base.x  = int2fp(100);
  3030. +  base.y  = int2fp(170);
  3031.    base.xm = 0;
  3032.    base.ym = 0;
  3033.    previous_base = old_base = base;
  3034. @@ -158,7 +159,7 @@
  3035.  }
  3036.  
  3037.  void
  3038. -Player::action(double frame_ratio)
  3039. +Player::action(fp frame_ratio)
  3040.  {
  3041.    bool jumped_in_solid = false;
  3042.  
  3043. @@ -211,7 +212,7 @@
  3044.            /* Land: */
  3045.            if (physic.get_velocity_y() < 0)
  3046.              {
  3047. -              base.y = (int)(((int)base.y / 32) * 32);
  3048. +              base.y = int2fp((fp2int(base.y) / 32) * 32);
  3049.                physic.set_velocity_y(0);
  3050.              }
  3051.  
  3052. @@ -222,11 +223,11 @@
  3053.  
  3054.        if(jumped_in_solid)
  3055.          {
  3056. -          if (isbrick(base.x, base.y) ||
  3057. -              isfullbox(base.x, base.y))
  3058. +          if (isbrick(fp2int(base.x), fp2int(base.y)) ||
  3059. +              isfullbox(fp2int(base.x), fp2int(base.y)))
  3060.              {
  3061. -              World::current()->trygrabdistro(base.x, base.y - 32,BOUNCE);
  3062. -              World::current()->trybumpbadguy(base.x, base.y - 64);
  3063. +              World::current()->trygrabdistro(base.x, base.y - int2fp(32),BOUNCE);
  3064. +              World::current()->trybumpbadguy(base.x, base.y - int2fp(64));
  3065.  
  3066.                World::current()->trybreakbrick(base.x, base.y, size == SMALL, RIGHT);
  3067.  
  3068. @@ -234,17 +235,17 @@
  3069.                World::current()->tryemptybox(base.x, base.y, RIGHT);
  3070.              }
  3071.  
  3072. -          if (isbrick(base.x+ 31, base.y) ||
  3073. -              isfullbox(base.x+ 31, base.y))
  3074. +          if (isbrick(fp2int(base.x)+ 31, fp2int(base.y)) ||
  3075. +              isfullbox(fp2int(base.x)+ 31, fp2int(base.y)))
  3076.              {
  3077. -              World::current()->trygrabdistro(base.x+ 31, base.y - 32,BOUNCE);
  3078. -              World::current()->trybumpbadguy(base.x+ 31, base.y - 64);
  3079. +              World::current()->trygrabdistro(base.x+ int2fp(31), base.y - int2fp(32),BOUNCE);
  3080. +              World::current()->trybumpbadguy(base.x+ int2fp(31), base.y - int2fp(64));
  3081.  
  3082.                if(size == BIG)
  3083. -                World::current()->trybreakbrick(base.x+ 31, base.y, size == SMALL, LEFT);
  3084. +                World::current()->trybreakbrick(base.x+ int2fp(31), base.y, size == SMALL, LEFT);
  3085.  
  3086. -              bumpbrick(base.x+ 31, base.y);
  3087. -              World::current()->tryemptybox(base.x+ 31, base.y, LEFT);
  3088. +              bumpbrick(base.x+ int2fp(31), base.y);
  3089. +              World::current()->tryemptybox(base.x+ int2fp(31), base.y, LEFT);
  3090.              }
  3091.          }
  3092.  
  3093. @@ -252,8 +253,11 @@
  3094.  
  3095.        if (jumped_in_solid)
  3096.          {
  3097. -          ++base.y;
  3098. -          ++old_base.y;
  3099. +          //FIXME: check use of ++
  3100. +          //++base.y;
  3101. +          //++old_base.y;
  3102. +          base.y += int2fp(1);
  3103. +          old_base.y += int2fp(1);
  3104.            if(on_ground())
  3105.              {
  3106.                /* Make sure jumping is off. */
  3107. @@ -275,75 +279,76 @@
  3108.  bool
  3109.  Player::on_ground()
  3110.  {
  3111. -  return ( issolid(base.x + base.width / 2, base.y + base.height) ||
  3112. -           issolid(base.x + 1, base.y + base.height) ||
  3113. -           issolid(base.x + base.width - 1, base.y + base.height)  );
  3114. +  return ( issolid(fp2int(base.x + base.width / 2), fp2int(base.y + base.height)) ||
  3115. +           issolid(fp2int(base.x) + 1, fp2int(base.y + base.height)) ||
  3116. +           issolid(fp2int(base.x + base.width) - 1, fp2int(base.y + base.height))  );
  3117.  }
  3118.  
  3119.  bool
  3120.  Player::under_solid()
  3121.  {
  3122. -  return ( issolid(base.x + base.width / 2, base.y) ||
  3123. -           issolid(base.x + 1, base.y) ||
  3124. -           issolid(base.x + base.width - 1, base.y)  );
  3125. +  return ( issolid(fp2int(base.x + base.width / 2), fp2int(base.y)) ||
  3126. +           issolid(fp2int(base.x) + 1, fp2int(base.y)) ||
  3127. +           issolid(fp2int(base.x + base.width) - 1, fp2int(base.y))  );
  3128.  }
  3129.  
  3130.  void
  3131.  Player::handle_horizontal_input()
  3132.  {
  3133. -  float vx = physic.get_velocity_x();
  3134. -  float vy = physic.get_velocity_y();
  3135. -  float ax = physic.get_acceleration_x();
  3136. -  float ay = physic.get_acceleration_y();
  3137. +  fp vx = physic.get_velocity_x();
  3138. +  fp vy = physic.get_velocity_y();
  3139. +  fp ax = physic.get_acceleration_x();
  3140. +  fp ay = physic.get_acceleration_y();
  3141.  
  3142. -  float dirsign = 0;
  3143. -  if(input.left == DOWN && input.right == UP && (!duck || physic.get_velocity_y() != 0)) {
  3144. +  int dirsign = 0;
  3145. +  if(input.left == DOWN && input.right == UP && (!duck || vy != 0)) {
  3146.        old_dir = dir;
  3147.        dir = LEFT;
  3148.        dirsign = -1;
  3149. -  } else if(input.left == UP && input.right == DOWN && (!duck || physic.get_velocity_y() != 0)) {
  3150. +  } else if(input.left == UP && input.right == DOWN && (!duck || vy != 0)) {
  3151.        old_dir = dir;
  3152.        dir = RIGHT;
  3153.        dirsign = 1;
  3154.    }
  3155.  
  3156.    if (input.fire == UP) {
  3157. -      ax = dirsign * WALK_ACCELERATION_X;
  3158. +      ax = dirsign * FP_WALK_ACCELERATION_X;
  3159.        // limit speed
  3160. -      if(vx >= MAX_WALK_XM && dirsign > 0) {
  3161. -        vx = MAX_WALK_XM;
  3162. +      if(vx >= FP_MAX_WALK_XM && dirsign > 0) {
  3163. +        vx = FP_MAX_WALK_XM;
  3164.          ax = 0;
  3165. -      } else if(vx <= -MAX_WALK_XM && dirsign < 0) {
  3166. -        vx = -MAX_WALK_XM;
  3167. +      } else if(vx <= -FP_MAX_WALK_XM && dirsign < 0) {
  3168. +        vx = -FP_MAX_WALK_XM;
  3169.          ax = 0;
  3170.        }
  3171.    } else {
  3172. -      ax = dirsign * RUN_ACCELERATION_X;
  3173. +      ax = dirsign * FP_RUN_ACCELERATION_X;
  3174.        // limit speed
  3175. -      if(vx >= MAX_RUN_XM && dirsign > 0) {
  3176. -        vx = MAX_RUN_XM;
  3177. +      if(vx >= FP_MAX_RUN_XM && dirsign > 0) {
  3178. +        vx = FP_MAX_RUN_XM;
  3179.          ax = 0;
  3180. -      } else if(vx <= -MAX_RUN_XM && dirsign < 0) {
  3181. -        vx = -MAX_RUN_XM;
  3182. +      } else if(vx <= -FP_MAX_RUN_XM && dirsign < 0) {
  3183. +        vx = -FP_MAX_RUN_XM;
  3184.          ax = 0;
  3185.        }
  3186.    }
  3187.  
  3188.    // we can reach WALK_SPEED without any acceleration
  3189. -  if(dirsign != 0 && fabs(vx) < WALK_SPEED) {
  3190. -    vx = dirsign * WALK_SPEED;
  3191. +  if(dirsign != 0 && fabs(vx) < FP_WALK_SPEED) {
  3192. +    vx = dirsign * FP_WALK_SPEED;
  3193.    }
  3194.  
  3195.    // changing directions?
  3196.    if(on_ground() && ((vx < 0 && dirsign >0) || (vx>0 && dirsign<0))) {
  3197. -      if(fabs(vx)>SKID_XM && !skidding_timer.check()) {
  3198. +      if(fabs(vx)>FP_SKID_XM && !skidding_timer.check()) {
  3199.            skidding_timer.start(SKID_TIME);
  3200.  #ifndef GP2X
  3201.            play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
  3202.  #else
  3203.       play_chunk(SND_SKID);
  3204.  #endif
  3205. -          ax *= 2.5;
  3206. +          //ax *= 2.5;
  3207. +          ax = ax*2 + ax/2;
  3208.        } else {
  3209.            ax *= 2;
  3210.        }
  3211. @@ -351,18 +356,20 @@
  3212.  
  3213.    // we get slower when not pressing any keys
  3214.    if(dirsign == 0) {
  3215. -      if(fabs(vx) < WALK_SPEED) {
  3216. +      if(abs(vx) < FP_WALK_SPEED) {
  3217.            vx = 0;
  3218.            ax = 0;
  3219.        } else if(vx < 0) {
  3220. -          ax = WALK_ACCELERATION_X * 1.5;
  3221. +          //ax = WALK_ACCELERATION_X * 1.5;
  3222. +          ax = FP_WALK_ACCELERATION_X + FP_WALK_ACCELERATION_X/2;
  3223.        } else {
  3224. -          ax = WALK_ACCELERATION_X * -1.5;
  3225. +          //ax = WALK_ACCELERATION_X * -1.5;
  3226. +          ax = -FP_WALK_ACCELERATION_X - FP_WALK_ACCELERATION_X/2;
  3227.        }
  3228.    }
  3229.  
  3230.    // if we're on ice slow down acceleration or deceleration
  3231. -  if (isice(base.x, base.y + base.height))
  3232. +  if (isice(fp2int(base.x), fp2int(base.y + base.height)))
  3233.    {
  3234.      /* the acceleration/deceleration rate on ice is inversely proportional to
  3235.       * the current velocity.
  3236. @@ -371,7 +378,7 @@
  3237.      // increasing 1 will increase acceleration/deceleration rate
  3238.      // decreasing 1 will decrease acceleration/deceleration rate
  3239.      //  must stay above zero, though
  3240. -    if (ax != 0) ax *= 1 / fabs(vx);
  3241. +    if (ax != 0) ax = fpmul(ax, fpdiv(int2fp(1), abs(vx)));
  3242.    }
  3243.  
  3244.    physic.set_velocity(vx, vy);
  3245. @@ -387,12 +394,14 @@
  3246.        if (on_ground())
  3247.          {
  3248.            // jump higher if we are running
  3249. -          if (fabs(physic.get_velocity_x()) > MAX_WALK_XM)
  3250. -            physic.set_velocity_y(5.8);
  3251. +          if (abs(physic.get_velocity_x()) > FP_MAX_WALK_XM)
  3252. +            physic.set_velocity_y(FP_RUN_JUMP_SPEED);
  3253.            else
  3254. -            physic.set_velocity_y(5.2);
  3255. +            physic.set_velocity_y(FP_WALK_JUMP_SPEED);
  3256.  
  3257. -          --base.y;
  3258. +          //FIXME: check use of --
  3259. +          //--base.y;
  3260. +          base.y -= int2fp(1);
  3261.            jumping = true;
  3262.            can_jump = false;
  3263.            if (size == SMALL)
  3264. @@ -418,9 +427,9 @@
  3265.        }
  3266.      }
  3267.  
  3268. -  if ( (issolid(base.x + base.width / 2, base.y + base.height + 64) ||
  3269. -        issolid(base.x + 1, base.y + base.height + 64) ||
  3270. -        issolid(base.x + base.width - 1, base.y + base.height + 64))
  3271. +  if ( (issolid(fp2int(base.x + base.width / 2), fp2int(base.y + base.height) + 64) ||
  3272. +        issolid(fp2int(base.x) + 1, fp2int(base.y + base.height) + 64) ||
  3273. +        issolid(fp2int(base.x + base.width) - 1, fp2int(base.y + base.height) + 64))
  3274.         && jumping  == false
  3275.         && can_jump == false
  3276.         && input.up == DOWN
  3277. @@ -481,16 +490,16 @@
  3278.    if (input.down == DOWN && size == BIG && !duck && physic.get_velocity_y() == 0 && on_ground())
  3279.      {
  3280.        duck = true;
  3281. -      base.height = 32;                            
  3282. -      base.y += 32;
  3283. +      base.height = int2fp(32);
  3284. +      base.y += int2fp(32);
  3285.        // changing base size confuses collision otherwise
  3286.        old_base = previous_base = base;
  3287.      }
  3288.    else if(input.down == UP && size == BIG && duck && physic.get_velocity_y() == 0 && on_ground())
  3289.      {
  3290.        duck = false;
  3291. -      base.y -= 32;
  3292. -      base.height = 64;
  3293. +      base.y -= int2fp(32);
  3294. +      base.height = int2fp(64);
  3295.        // changing base size confuses collision otherwise
  3296.        old_base = previous_base = base;                        
  3297.      }
  3298. @@ -503,8 +512,8 @@
  3299.      return;
  3300.    
  3301.    size = BIG;
  3302. -  base.height = 64;
  3303. -  base.y -= 32;
  3304. +  base.height = int2fp(64);
  3305. +  base.y -= int2fp(32);
  3306.  
  3307.    old_base = previous_base = base;
  3308.  }
  3309. @@ -526,15 +535,15 @@
  3310.    if (!dying)
  3311.      {
  3312.        World::current()->trygrabdistro(base.x, base.y, NO_BOUNCE);
  3313. -      World::current()->trygrabdistro(base.x+ 31, base.y, NO_BOUNCE);
  3314. +      World::current()->trygrabdistro(base.x+ int2fp(31), base.y, NO_BOUNCE);
  3315.  
  3316.        World::current()->trygrabdistro(base.x, base.y + base.height, NO_BOUNCE);
  3317. -      World::current()->trygrabdistro(base.x+ 31, base.y + base.height, NO_BOUNCE);
  3318. +      World::current()->trygrabdistro(base.x+ int2fp(31), base.y + base.height, NO_BOUNCE);
  3319.  
  3320.        if(size == BIG)
  3321.          {
  3322.            World::current()->trygrabdistro(base.x, base.y + base.height / 2, NO_BOUNCE);
  3323. -          World::current()->trygrabdistro(base.x+ 31, base.y + base.height / 2, NO_BOUNCE);
  3324. +          World::current()->trygrabdistro(base.x+ int2fp(31), base.y + base.height / 2, NO_BOUNCE);
  3325.          }
  3326.  
  3327.      }
  3328. @@ -561,7 +570,7 @@
  3329.      {
  3330.        if (dying == DYING_SQUISHED)
  3331.          {
  3332. -          smalltux_gameover->draw(base.x - scroll_x, base.y);
  3333. +          smalltux_gameover->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3334.          }
  3335.        else
  3336.          {
  3337. @@ -577,46 +586,46 @@
  3338.            if (duck && size != SMALL)
  3339.              {
  3340.                if (dir == RIGHT)
  3341. -                sprite->duck_right->draw(base.x - scroll_x, base.y);
  3342. +                sprite->duck_right->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3343.                else
  3344. -                sprite->duck_left->draw(base.x - scroll_x, base.y);
  3345. +                sprite->duck_left->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3346.              }
  3347.            else if (skidding_timer.started())
  3348.              {
  3349.                if (dir == RIGHT)
  3350. -                sprite->skid_right->draw(base.x - scroll_x, base.y);
  3351. +                sprite->skid_right->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3352.                else
  3353. -                sprite->skid_left->draw(base.x - scroll_x, base.y);
  3354. +                sprite->skid_left->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3355.              }
  3356.            else if (kick_timer.started())
  3357.              {
  3358.                if (dir == RIGHT)
  3359. -                sprite->kick_right->draw(base.x - scroll_x, base.y);
  3360. +                sprite->kick_right->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3361.                else
  3362. -                sprite->kick_left->draw(base.x - scroll_x, base.y);
  3363. +                sprite->kick_left->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3364.              }
  3365.            else if (physic.get_velocity_y() != 0)
  3366.              {
  3367.                if (dir == RIGHT)
  3368. -                sprite->jump_right->draw(base.x - scroll_x, base.y);
  3369. +                sprite->jump_right->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3370.                else
  3371. -                sprite->jump_left->draw(base.x - scroll_x, base.y);                  
  3372. +                sprite->jump_left->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3373.              }
  3374.            else
  3375.              {
  3376. -              if (fabsf(physic.get_velocity_x()) < 1.0f) // standing
  3377. +              if (abs(physic.get_velocity_x()) < int2fp(1)) // standing
  3378.                  {
  3379.                    if (dir == RIGHT)
  3380. -                    sprite->stand_right->draw( base.x - scroll_x, base.y);
  3381. +                    sprite->stand_right->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3382.                    else
  3383. -                    sprite->stand_left->draw( base.x - scroll_x, base.y);
  3384. +                    sprite->stand_left->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3385.                  }
  3386.                else // moving
  3387.                  {
  3388.                    if (dir == RIGHT)
  3389. -                    sprite->walk_right->draw(base.x - scroll_x, base.y);
  3390. +                    sprite->walk_right->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3391.                    else
  3392. -                    sprite->walk_left->draw(base.x - scroll_x, base.y);
  3393. +                    sprite->walk_left->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3394.                  }
  3395.              }
  3396.                        
  3397. @@ -624,9 +633,9 @@
  3398.            if (holding_something && physic.get_velocity_y() == 0 && !duck)
  3399.              {
  3400.                if (dir == RIGHT)
  3401. -                sprite->grab_right->draw(base.x - scroll_x, base.y);
  3402. +                sprite->grab_right->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3403.                else
  3404. -                sprite->grab_left->draw(base.x - scroll_x, base.y);
  3405. +                sprite->grab_left->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3406.              }
  3407.  
  3408.            // Draw blinking star overlay
  3409. @@ -634,16 +643,26 @@
  3410.               (invincible_timer.get_left() > TUX_INVINCIBLE_TIME_WARNING || global_frame_counter % 3))
  3411.              {
  3412.                if (size == SMALL || duck)
  3413. -                smalltux_star->draw(base.x - scroll_x, base.y);
  3414. +                smalltux_star->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3415.                else
  3416. -                largetux_star->draw(base.x - scroll_x, base.y);
  3417. +                largetux_star->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3418.              }
  3419.          }
  3420.      }    
  3421.    
  3422. -  if (debug_mode)
  3423. -    fillrect(base.x - scroll_x, base.y,
  3424. -             base.width, base.height, 75,75,75, 150);
  3425. +  if (debug_mode) {
  3426. +    fillrect(fp2int(base.x - scroll_x), fp2int(base.y),
  3427. +             fp2int(base.width), fp2int(base.height), 75,75,75, 150);
  3428. +   printf("scroll_x = %4.2f, player (%3.1f,%3.1f) v (%2.2f,%2.2f) a (%1.3f,%1.3f)        \r",
  3429. +          fp2float(scroll_x),
  3430. +          fp2float(base.x),
  3431. +          fp2float(base.y),
  3432. +          fp2float(physic.get_velocity_x()),
  3433. +          fp2float(physic.get_velocity_y()),
  3434. +          fp2float(physic.get_acceleration_x()),
  3435. +          fp2float(physic.get_acceleration_y()));
  3436. +  }
  3437. +
  3438.  }
  3439.  
  3440.  void
  3441. @@ -666,7 +685,7 @@
  3442.              {
  3443.                holding_something = true;
  3444.                pbad_c->mode = BadGuy::HELD;
  3445. -              pbad_c->base.y-=8;
  3446. +              pbad_c->base.y -= int2fp(8);
  3447.              }
  3448.            else if (pbad_c->mode == BadGuy::FLAT)
  3449.              {
  3450. @@ -735,7 +754,7 @@
  3451.        else
  3452.          {
  3453.            size = SMALL;
  3454. -          base.height = 32;
  3455. +          base.height = int2fp(32);
  3456.            duck = false;
  3457.          }
  3458.        safe_timer.start(TUX_SAFE_TIME);
  3459. @@ -744,9 +763,9 @@
  3460.      {
  3461.        physic.enable_gravity(true);
  3462.        physic.set_acceleration(0, 0);
  3463. -      physic.set_velocity(0, 7);
  3464. +      physic.set_velocity(0, FP_RUN_JUMP_SPEED);
  3465.        if(dying != DYING_SQUISHED)
  3466. -      --player_status.lives;
  3467. +        --player_status.lives;
  3468.        dying = DYING_SQUISHED;
  3469.      }
  3470.  }
  3471. @@ -761,9 +780,9 @@
  3472.  bool Player::is_dead()
  3473.  {
  3474.  #ifndef RES320X240
  3475. -  if(base.y > screen->h || base.x < scroll_x - AUTOSCROLL_DEAD_INTERVAL)  // last condition can happen in auto-scrolling
  3476. +  if(base.y > int2fp(screen->h) || base.x < scroll_x - int2fp(AUTOSCROLL_DEAD_INTERVAL))  // last condition can happen in auto-scrolling
  3477.  #else
  3478. -  if(base.y > 640 || base.x < scroll_x - AUTOSCROLL_DEAD_INTERVAL)  // last condition can happen in auto-scrolling
  3479. +    if(base.y > int2fp(640) || base.x < scroll_x - int2fp(AUTOSCROLL_DEAD_INTERVAL))  // last condition can happen in auto-scrolling
  3480.  #endif
  3481.      return true;
  3482.    else
  3483. @@ -776,7 +795,7 @@
  3484.  {
  3485.    got_coffee = false;
  3486.    size = SMALL;
  3487. -  base.height = 32;
  3488. +  base.height = int2fp(32);
  3489.  }
  3490.  
  3491.  void
  3492. @@ -791,9 +810,9 @@
  3493.  
  3494.    /* Keep in-bounds, vertically: */
  3495.  #ifndef RES320X240
  3496. -  if (base.y > screen->h)
  3497. +  if (base.y > int2fp(screen->h))
  3498.  #else
  3499. -  if (base.y > 640)
  3500. +    if (base.y > int2fp(640))
  3501.  #endif
  3502.      {
  3503.        kill(KILL);
  3504. @@ -812,11 +831,11 @@
  3505.    if(hor_autoscroll)
  3506.      {
  3507.      if(base.x == scroll_x)
  3508. -      if((issolid(base.x+32, base.y) || (size != SMALL && !duck && issolid(base.x+32, base.y+32))) && (dying == DYING_NOT))
  3509. +      if((issolid(fp2int(base.x)+32, fp2int(base.y)) || (size != SMALL && !duck && issolid(fp2int(base.x)+32, fp2int(base.y)+32))) && (dying == DYING_NOT))
  3510.          kill(KILL);
  3511.  
  3512. -    if(base.x + base.width > scroll_x + screen->w)
  3513. -      base.x = scroll_x + screen->w - base.width;
  3514. +    if(base.x + base.width > scroll_x + int2fp(screen->w))
  3515. +      base.x = scroll_x + int2fp(screen->w) - base.width;
  3516.      }
  3517.  }
  3518.  
  3519. diff -Naur supertux-0.1.3/src.bak/player.h supertux-0.1.3/src/player.h
  3520. --- supertux-0.1.3/src.bak/player.h 2014-12-06 18:00:56.000000000 -0500
  3521. +++ supertux-0.1.3/src/player.h 2014-12-06 18:04:19.000000000 -0500
  3522. @@ -28,6 +28,7 @@
  3523.  #include "collision.h"
  3524.  #include "sound.h"
  3525.  #include "physic.h"
  3526. +#include "fpmath.h"
  3527.  
  3528.  /* Times: */
  3529.  
  3530. @@ -137,7 +138,7 @@
  3531.    void init();
  3532.    int  key_event(SDLKey key, int state);
  3533.    void level_begin();
  3534. -  void action(double frame_ratio);
  3535. +  void action(fp frame_ratio);
  3536.    void handle_input();
  3537.    void grabdistros();
  3538.    void draw();
  3539. diff -Naur supertux-0.1.3/src.bak/scene.cpp supertux-0.1.3/src/scene.cpp
  3540. --- supertux-0.1.3/src.bak/scene.cpp    2014-12-06 18:00:56.000000000 -0500
  3541. +++ supertux-0.1.3/src/scene.cpp    2014-12-06 18:04:19.000000000 -0500
  3542. @@ -69,7 +69,7 @@
  3543.  }
  3544.  
  3545.  // FIXME: Move this into a view class
  3546. -float scroll_x;
  3547. +fp scroll_x;
  3548.  
  3549.  unsigned int global_frame_counter;
  3550.  
  3551. diff -Naur supertux-0.1.3/src.bak/scene.h supertux-0.1.3/src/scene.h
  3552. --- supertux-0.1.3/src.bak/scene.h  2014-12-06 18:00:56.000000000 -0500
  3553. +++ supertux-0.1.3/src/scene.h  2014-12-06 18:04:19.000000000 -0500
  3554. @@ -22,6 +22,7 @@
  3555.  
  3556.  #include "texture.h"
  3557.  #include "timer.h"
  3558. +#include "fpmath.h"
  3559.  
  3560.  #define FRAME_RATE 10 // 100 Frames per second (10ms)
  3561.  
  3562. @@ -46,7 +47,7 @@
  3563.  
  3564.  extern PlayerStatus player_status;
  3565.  
  3566. -extern float scroll_x;
  3567. +extern fp scroll_x;
  3568.  extern unsigned int global_frame_counter;
  3569.  
  3570.  #endif /*SUPERTUX_SCENE_H*/
  3571. diff -Naur supertux-0.1.3/src.bak/screen.cpp supertux-0.1.3/src/screen.cpp
  3572. --- supertux-0.1.3/src.bak/screen.cpp   2014-12-06 18:00:56.000000000 -0500
  3573. +++ supertux-0.1.3/src/screen.cpp   2014-12-07 09:41:33.000000000 -0500
  3574. @@ -71,21 +71,26 @@
  3575.      {
  3576.        glBegin(GL_QUADS);
  3577.        glColor3ub(top_clr.red, top_clr.green, top_clr.blue);
  3578. -      glVertex2f(0, 0);
  3579. -      glVertex2f(640, 0);
  3580. +      glVertex2i(0, 0);
  3581. +      glVertex2i(640, 0);
  3582.        glColor3ub(bot_clr.red, bot_clr.green, bot_clr.blue);
  3583. -      glVertex2f(640, 480);
  3584. -      glVertex2f(0, 480);
  3585. +      glVertex2i(640, 480);
  3586. +      glVertex2i(0, 480);
  3587.        glEnd();
  3588.      }
  3589.    else
  3590.    {
  3591.  #endif
  3592. -    for(float y = 0; y < 480; y += 2)
  3593. -      fillrect(0, (int)y, 640, 2,
  3594. -                     (int)(((float)(top_clr.red-bot_clr.red)/(0-480)) * y + top_clr.red),
  3595. -                     (int)(((float)(top_clr.green-bot_clr.green)/(0-480)) * y + top_clr.green),
  3596. -                     (int)(((float)(top_clr.blue-bot_clr.blue)/(0-480)) * y + top_clr.blue), 255);
  3597. +//    for(float y = 0; y < 480; y += 2)
  3598. +//      fillrect(0, (int)y, 640, 2,
  3599. +//                     (int)(((float)(top_clr.red-bot_clr.red)/(0-480)) * y + top_clr.red),
  3600. +//                     (int)(((float)(top_clr.green-bot_clr.green)/(0-480)) * y + top_clr.green),
  3601. +//                     (int)(((float)(top_clr.blue-bot_clr.blue)/(0-480)) * y + top_clr.blue), 255);
  3602. +    for(int y = 0; y < 480; y += 2)
  3603. +      fillrect(0, y, 640, 2,
  3604. +               (top_clr.red - bot_clr.red) * y / (0-480) + top_clr.red,
  3605. +               (top_clr.green - bot_clr.green) * y / (0-480) + top_clr.green,
  3606. +               (top_clr.blue - bot_clr.blue) * y / (0-480) + top_clr.blue, 255);
  3607.  /* calculates the color for each line, based in the generic equation for functions: y = mx + b */
  3608.  
  3609.  #ifndef NOOPENGL
  3610. @@ -110,25 +115,25 @@
  3611.  
  3612.  void fade(Surface *surface, int seconds, bool fade_out)
  3613.  {
  3614. -float alpha;
  3615. +fp alpha;
  3616.  if (fade_out)
  3617.    alpha = 0;
  3618.  else
  3619. -  alpha = 255;
  3620. +  alpha = int2fp(255);
  3621.  
  3622.    int cur_time, old_time;
  3623.    cur_time = SDL_GetTicks();
  3624.  
  3625. -  while(alpha >= 0 && alpha < 256)
  3626. +  while(alpha >= 0 && alpha < int2fp(256))
  3627.      {
  3628. -    surface->draw(0,0,(int)alpha);
  3629. +    surface->draw(0,0,fp2int(alpha));
  3630.      flipscreen();
  3631.  
  3632.      old_time = cur_time;
  3633.      cur_time = SDL_GetTicks();
  3634.  
  3635.      /* Calculate the next alpha value */
  3636. -    float calc = (float) ((cur_time - old_time) / seconds);
  3637. +    fp calc = (int2fp(cur_time - old_time) / seconds);
  3638.      if(fade_out)
  3639.        alpha += 255 * calc;
  3640.      else
  3641. @@ -279,7 +284,7 @@
  3642.  
  3643.  /* --- FILL A RECT --- */
  3644.  
  3645. -void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
  3646. +void fillrect(int x, int y, int w, int h, int r, int g, int b, int a)
  3647.  {
  3648.  if(w < 0)
  3649.     {
  3650. @@ -307,10 +312,10 @@
  3651.        glColor4ub(r, g, b,a);
  3652.  
  3653.        glBegin(GL_POLYGON);
  3654. -      glVertex2f(x, y);
  3655. -      glVertex2f(x+w, y);
  3656. -      glVertex2f(x+w, y+h);
  3657. -      glVertex2f(x, y+h);
  3658. +      glVertex2i(x, y);
  3659. +      glVertex2i(x+w, y);
  3660. +      glVertex2i(x+w, y+h);
  3661. +      glVertex2i(x, y+h);
  3662.        glEnd();
  3663.        glDisable(GL_BLEND);
  3664.      }
  3665. @@ -320,10 +325,10 @@
  3666.        SDL_Rect src, rect;
  3667.        SDL_Surface *temp = NULL;
  3668.  
  3669. -      rect.x = (int)x;
  3670. -      rect.y = (int)y;
  3671. -      rect.w = (int)w;
  3672. -      rect.h = (int)h;
  3673. +      rect.x = x;
  3674. +      rect.y = y;
  3675. +      rect.w = w;
  3676. +      rect.h = h;
  3677.  
  3678.        if(a != 255)
  3679.          {
  3680. diff -Naur supertux-0.1.3/src.bak/screen.h supertux-0.1.3/src/screen.h
  3681. --- supertux-0.1.3/src.bak/screen.h 2014-12-06 18:00:56.000000000 -0500
  3682. +++ supertux-0.1.3/src/screen.h 2014-12-06 18:04:19.000000000 -0500
  3683. @@ -47,7 +47,7 @@
  3684.  void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a);
  3685.  void clearscreen(int r, int g, int b);
  3686.  void drawgradient(Color top_clr, Color bot_clr);
  3687. -void fillrect(float x, float y, float w, float h, int r, int g, int b, int a);
  3688. +void fillrect(int x, int y, int w, int h, int r, int g, int b, int a);
  3689.  //void black_fade(Surface* surface, int seconds, bool fade_out);
  3690.  void fade(const std::string& surface, int seconds, bool fade_out);
  3691.  void updatescreen(void);
  3692. diff -Naur supertux-0.1.3/src.bak/setup.cpp supertux-0.1.3/src/setup.cpp
  3693. --- supertux-0.1.3/src.bak/setup.cpp    2014-12-06 18:00:56.000000000 -0500
  3694. +++ supertux-0.1.3/src/setup.cpp    2014-12-07 09:45:48.000000000 -0500
  3695. @@ -423,7 +423,11 @@
  3696.  #else
  3697.    options_menu->additem(MN_DEACTIVE,"OpenGL (not supported)",use_gl, 0, MNID_OPENGL);
  3698.  #endif
  3699. +#ifndef NOWINDOWED
  3700.    options_menu->additem(MN_TOGGLE,"Fullscreen",use_fullscreen,0, MNID_FULLSCREEN);
  3701. +#else
  3702. +  options_menu->additem(MN_DEACTIVE,"Fullscreen (always on)",use_fullscreen, 0, MNID_FULLSCREEN);
  3703. +#endif
  3704.  #endif
  3705.    if(audio_device)
  3706.      {
  3707. @@ -777,6 +781,10 @@
  3708.            exit(1);
  3709.          }
  3710.      }
  3711. +  if ((screen != NULL) && (debug_mode))
  3712. +    {
  3713. +      printf("Screen bpp = %d\n", screen->format->BitsPerPixel);
  3714. +    }
  3715.  }
  3716.  
  3717.  void st_video_setup_gl(void)
  3718. diff -Naur supertux-0.1.3/src.bak/special.cpp supertux-0.1.3/src/special.cpp
  3719. --- supertux-0.1.3/src.bak/special.cpp  2014-12-06 18:00:56.000000000 -0500
  3720. +++ supertux-0.1.3/src/special.cpp  2014-12-07 11:34:37.000000000 -0500
  3721. @@ -30,6 +30,7 @@
  3722.  #include "player.h"
  3723.  #include "sprite_manager.h"
  3724.  #include "resources.h"
  3725. +#include "fpmath.h"
  3726.  
  3727.  Sprite* img_bullet;
  3728.  Sprite* img_star;
  3729. @@ -37,31 +38,26 @@
  3730.  Sprite* img_iceflower;
  3731.  Sprite* img_1up;
  3732.  
  3733. -#define GROWUP_SPEED 1.0f
  3734. -
  3735. -#define BULLET_STARTING_YM 0
  3736. -#define BULLET_XM 6
  3737. -
  3738.  void
  3739. -Bullet::init(float x, float y, float xm, Direction dir)
  3740. +Bullet::init(fp x, fp y, fp xm, Direction dir)
  3741.  {
  3742.    life_count = 3;
  3743. -  base.width = 4;
  3744. -  base.height = 4;
  3745. +  base.width = int2fp(4);
  3746. +  base.height = int2fp(4);
  3747.  
  3748.    if (dir == RIGHT)
  3749.      {
  3750. -      base.x = x + 32;
  3751. -      base.xm = BULLET_XM + xm;
  3752. +      base.x = x + int2fp(32);
  3753. +      base.xm = FP_BULLET_XM + xm;
  3754.      }
  3755.    else
  3756.      {
  3757.        base.x = x;
  3758. -      base.xm = -BULLET_XM + xm;
  3759. +      base.xm = -FP_BULLET_XM + xm;
  3760.      }
  3761.  
  3762.    base.y = y;
  3763. -  base.ym = BULLET_STARTING_YM;
  3764. +  base.ym = FP_BULLET_STARTING_YM;
  3765.    old_base = base;
  3766.  }
  3767.  
  3768. @@ -81,43 +77,48 @@
  3769.  }
  3770.  
  3771.  void
  3772. -Bullet::action(double frame_ratio)
  3773. +Bullet::action(fp frame_ratio)
  3774.  {
  3775. -  frame_ratio *= 0.5f;
  3776. +  frame_ratio /= 2;
  3777.  
  3778. -  float old_y = base.y;
  3779. +  fp old_y = base.y;
  3780.  
  3781. -  base.x = base.x + base.xm * frame_ratio;
  3782. -  base.y = base.y + base.ym * frame_ratio;
  3783. +  base.x = base.x + fpmul(base.xm, frame_ratio);
  3784. +  base.y = base.y + fpmul(base.ym, frame_ratio);
  3785.  
  3786.    collision_swept_object_map(&old_base,&base);
  3787.        
  3788. -  if (issolid(base.x, base.y + 4) || issolid(base.x, base.y))
  3789. +  int base_x = fp2int(base.x);
  3790. +  int base_y = fp2int(base.y);      
  3791. +  if (issolid(base_x, base_y + 4) || issolid(base_x, base_y))
  3792.      {
  3793.        base.y  = old_y;
  3794.        base.ym = -base.ym;    
  3795. -      if (base.ym > 9)
  3796. -        base.ym = 9;
  3797. -      else if (base.ym < -9)
  3798. -        base.ym = -9;
  3799. +      if (base.ym > int2fp(9))
  3800. +        base.ym = int2fp(9);
  3801. +      else if (base.ym < int2fp(-9))
  3802. +        base.ym = int2fp(-9);
  3803.        life_count -= 1;
  3804.      }
  3805.  
  3806. -  base.ym = base.ym + 0.5 * frame_ratio;
  3807. +  base.ym = base.ym + frame_ratio/2;
  3808. +
  3809. +  base_x = fp2int(base.x);
  3810. +  base_y = fp2int(base.y);      
  3811.  
  3812.  #ifndef RES320X240  
  3813.    if (base.x < scroll_x ||
  3814. -      base.x > scroll_x + screen->w ||
  3815. -      base.y > screen->h ||
  3816. -      issolid(base.x + 4, base.y + 2) ||
  3817. -      issolid(base.x, base.y + 2) ||
  3818. +      base.x > scroll_x + int2fp(screen->w) ||
  3819. +      base.y > int2fp(screen->h) ||
  3820. +      issolid(base_x + 4, base_y + 2) ||
  3821. +      issolid(base_x, base_y + 2) ||
  3822.        life_count <= 0)
  3823.  #else
  3824.    if (base.x < scroll_x ||
  3825. -      base.x > scroll_x + 640 ||
  3826. -      base.y > 480 ||
  3827. -      issolid(base.x + 4, base.y + 2) ||
  3828. -      issolid(base.x, base.y + 2) ||
  3829. +      base.x > scroll_x + int2fp(640) ||
  3830. +      base.y > int2fp(480) ||
  3831. +      issolid(base_x + 4, base_y + 2) ||
  3832. +      issolid(base_x, base_y + 2) ||
  3833.        life_count <= 0)
  3834.  #endif
  3835.      {
  3836. @@ -131,13 +132,13 @@
  3837.  {
  3838.  #ifndef RES320X240
  3839.    if (base.x >= scroll_x - base.width &&
  3840. -      base.x <= scroll_x + screen->w)
  3841. +      base.x <= scroll_x + int2fp(screen->w))
  3842.  #else
  3843.    if (base.x >= scroll_x - base.width &&
  3844. -      base.x <= scroll_x + 640)
  3845. +      base.x <= scroll_x + int2fp(640))
  3846.  #endif
  3847.      {
  3848. -      img_bullet->draw(base.x - scroll_x, base.y);
  3849. +      img_bullet->draw(fp2int(base.x - scroll_x), fp2int(base.y));
  3850.      }
  3851.  }
  3852.  
  3853. @@ -150,12 +151,12 @@
  3854.  }
  3855.  
  3856.  void
  3857. -Upgrade::init(float x_, float y_, Direction dir_, UpgradeKind kind_)
  3858. +Upgrade::init(fp x_, fp y_, Direction dir_, UpgradeKind kind_)
  3859.  {
  3860.    kind = kind_;
  3861.    dir = dir_;
  3862.    
  3863. -  base.width = 32;
  3864. +  base.width = int2fp(32);
  3865.    base.height = 0;
  3866.    base.x = x_;
  3867.    base.y = y_;
  3868. @@ -165,15 +166,15 @@
  3869.    physic.enable_gravity(false);
  3870.  
  3871.    if(kind == UPGRADE_1UP || kind == UPGRADE_HERRING) {
  3872. -    physic.set_velocity(dir == LEFT ? -1 : 1, 4);
  3873. +    physic.set_velocity(dir == LEFT ? -FP_UPGRADE_SPEED_X : FP_UPGRADE_SPEED_X, FP_UPGRADE_SPEED_Y);
  3874.      physic.enable_gravity(true);
  3875. -    base.height = 32;
  3876. +    base.height = int2fp(32);
  3877.    } else if (kind == UPGRADE_ICEFLOWER) {
  3878.      // nothing
  3879.    } else if (kind == UPGRADE_GROWUP) {
  3880. -    physic.set_velocity(dir == LEFT ? -GROWUP_SPEED : GROWUP_SPEED, 0);
  3881. +    physic.set_velocity(dir == LEFT ? -FP_GROWUP_SPEED : FP_GROWUP_SPEED, 0);
  3882.    } else {
  3883. -    physic.set_velocity(dir == LEFT ? -2 : 2, 0);
  3884. +    physic.set_velocity(dir == LEFT ? -FP_BOUNCE_SPEED : FP_BOUNCE_SPEED, 0);
  3885.    }
  3886.  }
  3887.  
  3888. @@ -193,28 +194,28 @@
  3889.  }
  3890.  
  3891.  void
  3892. -Upgrade::action(double frame_ratio)
  3893. +Upgrade::action(fp frame_ratio)
  3894.  {
  3895.    if (kind == UPGRADE_ICEFLOWER || kind == UPGRADE_GROWUP) {
  3896. -    if (base.height < 32) {
  3897. +    if (base.height < int2fp(32)) {
  3898.        /* Rise up! */
  3899. -      base.height = base.height + 0.7 * frame_ratio;
  3900. -      if(base.height > 32)
  3901. -        base.height = 32;
  3902. +      base.height = base.height + fpmul(FP_RISE_RATIO, frame_ratio);
  3903. +      if(base.height > int2fp(32))
  3904. +        base.height = int2fp(32);
  3905.  
  3906.        return;
  3907.      }
  3908.    }
  3909.  
  3910.    /* Away from the screen? Kill it! */
  3911. -  if(base.x < scroll_x - OFFSCREEN_DISTANCE) {
  3912. +  if(base.x < scroll_x - int2fp(OFFSCREEN_DISTANCE)) {
  3913.        remove_me();
  3914.        return;
  3915.    }
  3916.  #ifndef RES320X240
  3917. -  if(base.y > screen->h) {
  3918. +  if(base.y > int2fp(screen->h)) {
  3919.  #else
  3920. -  if(base.y > 640) {
  3921. +    if(base.y > int2fp(640)) {
  3922.  #endif
  3923.      remove_me();
  3924.      return;
  3925. @@ -230,21 +231,21 @@
  3926.    if(kind == UPGRADE_GROWUP || kind == UPGRADE_HERRING) {
  3927.      // falling?
  3928.      if(physic.get_velocity_y() != 0) {
  3929. -      if(issolid(base.x, base.y + base.height)) {
  3930. -        base.y = int(base.y / 32) * 32;
  3931. -        old_base = base;                        
  3932. +      if(issolid(fp2int(base.x), fp2int(base.y + base.height))) {
  3933. +        base.y = int2fp((fp2int(base.y) / 32) * 32);
  3934. +        old_base = base;
  3935.          if(kind == UPGRADE_GROWUP) {
  3936.            physic.enable_gravity(false);
  3937. -          physic.set_velocity(dir == LEFT ? -GROWUP_SPEED : GROWUP_SPEED, 0);
  3938. +          physic.set_velocity(dir == LEFT ? -FP_GROWUP_SPEED : FP_GROWUP_SPEED, 0);
  3939.          } else if(kind == UPGRADE_HERRING) {
  3940. -          physic.set_velocity(dir == LEFT ? -2 : 2, 3);
  3941. +          physic.set_velocity(dir == LEFT ? -FP_BOUNCE_SPEED : FP_BOUNCE_SPEED, FP_BOUNCE_SPEED);
  3942.          }
  3943.        }
  3944.      } else {
  3945.        if((physic.get_velocity_x() < 0
  3946. -            && !issolid(base.x+base.width, base.y + base.height))
  3947. +            && !issolid(fp2int(base.x+base.width), fp2int(base.y + base.height)))
  3948.          || (physic.get_velocity_x() > 0
  3949. -            && !issolid(base.x, base.y + base.height))) {
  3950. +            && !issolid(fp2int(base.x), fp2int(base.y + base.height)))) {
  3951.          physic.enable_gravity(true);
  3952.        }
  3953.      }
  3954. @@ -253,9 +254,9 @@
  3955.    // horizontal bounce?
  3956.    if(kind == UPGRADE_GROWUP || kind == UPGRADE_HERRING) {
  3957.      if (  (physic.get_velocity_x() < 0
  3958. -          && issolid(base.x, (int) base.y + base.height/2))
  3959. +          && issolid(fp2int(base.x), fp2int(base.y + base.height/2)))
  3960.          ||  (physic.get_velocity_x() > 0
  3961. -          && issolid(base.x + base.width, (int) base.y + base.height/2))) {
  3962. +          && issolid(fp2int(base.x + base.width), fp2int(base.y + base.height/2)))) {
  3963.          physic.set_velocity(-physic.get_velocity_x(),physic.get_velocity_y());
  3964.          dir = dir == LEFT ? RIGHT : LEFT;
  3965.      }
  3966. @@ -272,13 +273,13 @@
  3967.  
  3968.  
  3969.  #ifndef RES320X240
  3970. -      dest.x = (int)(base.x - scroll_x);
  3971. +      dest.x = fp2int(base.x - scroll_x);
  3972.  #else
  3973. -      dest.x = (int)(base.x - scroll_x)/2;
  3974. +      dest.x = fp2int(base.x - scroll_x)/2;
  3975.  #endif
  3976. -      dest.y = (int)(base.y + 32 - base.height);
  3977. +      dest.y = fp2int(base.y - base.height) + 32;
  3978.        dest.w = 32;
  3979. -      dest.h = (int)base.height;
  3980. +      dest.h = fp2int(base.height);
  3981.  
  3982.        if (kind == UPGRADE_GROWUP)
  3983.          img_growup->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
  3984. @@ -294,21 +295,22 @@
  3985.        if (kind == UPGRADE_GROWUP)
  3986.          {
  3987.            img_growup->draw(
  3988. -                       base.x - scroll_x, base.y);
  3989. +                       fp2int(base.x - scroll_x), fp2int(base.y));
  3990.          }
  3991.        else if (kind == UPGRADE_ICEFLOWER)
  3992.          {
  3993.            img_iceflower->draw(
  3994. -                       base.x - scroll_x, base.y);
  3995. +                       fp2int(base.x - scroll_x), fp2int(base.y));
  3996.          }
  3997.        else if (kind == UPGRADE_HERRING)
  3998.          {
  3999.            img_star->draw(
  4000. -                       base.x - scroll_x, base.y);
  4001. +                       fp2int(base.x - scroll_x), fp2int(base.y));
  4002.          }
  4003.        else if (kind == UPGRADE_1UP)
  4004.          {
  4005. -          img_1up->draw( base.x - scroll_x, base.y);
  4006. +          img_1up->draw(
  4007. +                       fp2int(base.x - scroll_x), fp2int(base.y));
  4008.          }
  4009.      }
  4010.  }
  4011. @@ -327,7 +329,7 @@
  4012.  #endif
  4013.    
  4014.    // do a little jump and change direction
  4015. -  physic.set_velocity(-physic.get_velocity_x(), 3);
  4016. +  physic.set_velocity(-physic.get_velocity_x(), FP_BUMP_SPEED);
  4017.    dir = dir == LEFT ? RIGHT : LEFT;
  4018.    physic.enable_gravity(true);
  4019.  }
  4020. diff -Naur supertux-0.1.3/src.bak/special.h supertux-0.1.3/src/special.h
  4021. --- supertux-0.1.3/src.bak/special.h    2014-12-06 18:00:56.000000000 -0500
  4022. +++ supertux-0.1.3/src/special.h    2014-12-06 18:04:19.000000000 -0500
  4023. @@ -27,6 +27,7 @@
  4024.  #include "collision.h"
  4025.  #include "player.h"
  4026.  #include "physic.h"
  4027. +#include "fpmath.h"
  4028.  
  4029.  /* Upgrade types: */
  4030.  
  4031. @@ -47,8 +48,8 @@
  4032.    Direction  dir;
  4033.    Physic physic;
  4034.  
  4035. -  void init(float x, float y, Direction dir, UpgradeKind kind);
  4036. -  void action(double frame_ratio);
  4037. +  void init(fp x, fp y, Direction dir, UpgradeKind kind);
  4038. +  void action(fp frame_ratio);
  4039.    void draw();
  4040.    void collision(void* p_c_object, int c_object, CollisionType type);
  4041.    std::string type() { return "Upgrade"; };
  4042. @@ -72,8 +73,8 @@
  4043.    base_type base;
  4044.    base_type old_base;
  4045.    
  4046. -  void init(float x, float y, float xm, Direction dir);
  4047. -  void action(double frame_ratio);
  4048. +  void init(fp x, fp y, fp xm, Direction dir);
  4049. +  void action(fp frame_ratio);
  4050.    void draw();
  4051.    void collision(int c_object);
  4052.    std::string type() { return "Bullet"; };
  4053. diff -Naur supertux-0.1.3/src.bak/sprite.cpp supertux-0.1.3/src/sprite.cpp
  4054. --- supertux-0.1.3/src.bak/sprite.cpp   2014-12-06 18:00:56.000000000 -0500
  4055. +++ supertux-0.1.3/src/sprite.cpp   2014-12-06 18:04:19.000000000 -0500
  4056. @@ -73,7 +73,7 @@
  4057.  }
  4058.  
  4059.  void
  4060. -Sprite::draw(float x, float y)
  4061. +Sprite::draw(int x, int y)
  4062.  {
  4063.    time = SDL_GetTicks();
  4064.    unsigned int frame = get_current_frame();
  4065. @@ -83,7 +83,7 @@
  4066.  }
  4067.  
  4068.  void
  4069. -Sprite::draw_part(float sx, float sy, float x, float y, float w, float h)
  4070. +Sprite::draw_part(int sx, int sy, int x, int y, int w, int h)
  4071.  {
  4072.    time = SDL_GetTicks();
  4073.    unsigned int frame = get_current_frame();
  4074. diff -Naur supertux-0.1.3/src.bak/sprite.h supertux-0.1.3/src/sprite.h
  4075. --- supertux-0.1.3/src.bak/sprite.h 2014-12-06 18:00:56.000000000 -0500
  4076. +++ supertux-0.1.3/src/sprite.h 2014-12-06 18:04:19.000000000 -0500
  4077. @@ -55,8 +55,8 @@
  4078.  
  4079.    /** Update the sprite and process to the next frame */
  4080.    void update(float delta);
  4081. -  void draw(float x, float y);
  4082. -  void draw_part(float sx, float sy, float x, float y, float w, float h);
  4083. +  void draw(int x, int y);
  4084. +  void draw_part(int sx, int sy, int x, int y, int w, int h);
  4085.    int get_current_frame() const;
  4086.  
  4087.    std::string get_name() const { return name; }
  4088. diff -Naur supertux-0.1.3/src.bak/supertux.cpp supertux-0.1.3/src/supertux.cpp
  4089. --- supertux-0.1.3/src.bak/supertux.cpp 2014-12-06 18:00:56.000000000 -0500
  4090. +++ supertux-0.1.3/src/supertux.cpp 2014-12-06 18:04:19.000000000 -0500
  4091. @@ -33,12 +33,18 @@
  4092.  #include "resources.h"
  4093.  #include "texture.h"
  4094.  #include "tile.h"
  4095. +#include "fpmath.h"
  4096.  
  4097.  int main(int argc, char * argv[])
  4098.  {
  4099.    st_directory_setup();
  4100.    parseargs(argc, argv);
  4101.    
  4102. +  if (debug_mode) {
  4103. +    printf("fpmath test: 3.5 * 8.6 = %2.2f\n", fp2float(fpmul(float2fp(3.5), float2fp(8.6))));
  4104. +    printf("fpmath test: 3.5 / 8.6 = %2.2f\n", fp2float(fpdiv(float2fp(3.5), float2fp(8.6))));
  4105. +  }
  4106. +
  4107.    st_audio_setup();
  4108.    st_video_setup();
  4109.    st_joystick_setup();
  4110. diff -Naur supertux-0.1.3/src.bak/text.cpp supertux-0.1.3/src/text.cpp
  4111. --- supertux-0.1.3/src.bak/text.cpp 2014-12-06 18:00:57.000000000 -0500
  4112. +++ supertux-0.1.3/src/text.cpp 2014-12-07 10:12:49.000000000 -0500
  4113. @@ -24,6 +24,7 @@
  4114.  #include "defines.h"
  4115.  #include "screen.h"
  4116.  #include "text.h"
  4117. +#include "fpmath.h"
  4118.  #include "sound.h"
  4119.  
  4120.  Text::Text(const std::string& file, int kind_, int w_, int h_)
  4121. @@ -234,22 +235,21 @@
  4122.  /* --- SCROLL TEXT FUNCTION --- */
  4123.  
  4124.  #define MAX_VEL     10
  4125. -#define SPEED_INC   0.01
  4126.  #define SCROLL      60
  4127.  #define ITEMS_SPACE 4
  4128.  
  4129. -void display_text_file(const std::string& file, const std::string& surface, float scroll_speed)
  4130. +void display_text_file(const std::string& file, const std::string& surface, fp scroll_speed)
  4131.  {
  4132.    Surface* sur = new Surface(datadir + surface, IGNORE_ALPHA);
  4133.    display_text_file(file, sur, scroll_speed);
  4134.    delete sur;
  4135.  }
  4136.  
  4137. -void display_text_file(const std::string& file, Surface* surface, float scroll_speed)
  4138. +void display_text_file(const std::string& file, Surface* surface, fp scroll_speed)
  4139.  {
  4140.    int done;
  4141. -  float scroll;
  4142. -  float speed;
  4143. +  fp scroll;
  4144. +  fp speed;
  4145.    int y;
  4146.    int length;
  4147.    FILE* fi;
  4148. @@ -297,15 +297,15 @@
  4149.              switch(event.key.keysym.sym)
  4150.                {
  4151.                case SDLK_UP:
  4152. -                speed -= SPEED_INC;
  4153. +                speed -= FP_SPEED_INC;
  4154.                  break;
  4155.                case SDLK_DOWN:
  4156. -                speed += SPEED_INC;
  4157. +                speed += FP_SPEED_INC;
  4158.                  break;
  4159.                case SDLK_SPACE:
  4160.                case SDLK_RETURN:
  4161.                  if(speed >= 0)
  4162. -                  scroll += SCROLL;
  4163. +                  scroll += int2fp(SCROLL);
  4164.                  break;
  4165.                case SDLK_ESCAPE:
  4166.                  done = 1;
  4167. @@ -339,10 +339,10 @@
  4168.              break;
  4169.            }
  4170.  
  4171. -      if(speed > MAX_VEL)
  4172. -        speed = MAX_VEL;
  4173. -      else if(speed < -MAX_VEL)
  4174. -        speed = -MAX_VEL;
  4175. +      if(speed > int2fp(MAX_VEL))
  4176. +        speed = int2fp(MAX_VEL);
  4177. +      else if(speed < int2fp(-MAX_VEL))
  4178. +        speed = int2fp(-MAX_VEL);
  4179.  
  4180.        /* draw the credits */
  4181.        surface->draw_bg();
  4182. @@ -353,7 +353,7 @@
  4183.          switch(names.item[i][0])
  4184.            {
  4185.            case ' ':
  4186. -            white_small_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
  4187. +            white_small_text->drawf(names.item[i]+1, 0, screen->h+y-fp2int(scroll),
  4188.                  A_HMIDDLE, A_TOP, 1);
  4189.              y += white_small_text->h+ITEMS_SPACE;
  4190.  #ifdef RES320X240
  4191. @@ -361,7 +361,7 @@
  4192.  #endif
  4193.              break;
  4194.            case '   ':
  4195. -            white_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
  4196. +            white_text->drawf(names.item[i]+1, 0, screen->h+y-fp2int(scroll),
  4197.                  A_HMIDDLE, A_TOP, 1);
  4198.              y += white_text->h+ITEMS_SPACE;
  4199.  #ifdef RES320X240
  4200. @@ -370,9 +370,9 @@
  4201.              break;
  4202.            case '-':
  4203.  #ifdef RES320X240
  4204. -            white_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll), A_HMIDDLE, A_TOP, 3);
  4205. +            white_text->drawf(names.item[i]+1, 0, screen->h+y-fp2int(scroll), A_HMIDDLE, A_TOP, 3);
  4206.  #else
  4207. -            white_big_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll), A_HMIDDLE, A_TOP, 3);
  4208. +            white_big_text->drawf(names.item[i]+1, 0, screen->h+y-fp2int(scroll), A_HMIDDLE, A_TOP, 3);
  4209.  #endif
  4210.              y += white_big_text->h+ITEMS_SPACE;
  4211.  #ifdef RES320X240
  4212. @@ -380,7 +380,7 @@
  4213.  #endif
  4214.              break;
  4215.            default:
  4216. -            blue_text->drawf(names.item[i], 0, screen->h+y-int(scroll),
  4217. +            blue_text->drawf(names.item[i], 0, screen->h+y-fp2int(scroll),
  4218.                  A_HMIDDLE, A_TOP, 1);
  4219.              y += blue_text->h+ITEMS_SPACE;
  4220.  #ifdef RES320X240
  4221. @@ -392,7 +392,7 @@
  4222.  
  4223.        flipscreen();
  4224.  
  4225. -      if(screen->h+y-scroll < 0 && 20+screen->h+y-scroll < 0)
  4226. +      if(int2fp(screen->h+y)-scroll < 0 && int2fp(20+screen->h+y)-scroll < 0)
  4227.          done = 1;
  4228.  
  4229.        Uint32 ticks = SDL_GetTicks();
  4230. diff -Naur supertux-0.1.3/src.bak/text.h supertux-0.1.3/src/text.h
  4231. --- supertux-0.1.3/src.bak/text.h   2014-12-06 18:00:57.000000000 -0500
  4232. +++ supertux-0.1.3/src/text.h   2014-12-06 18:04:19.000000000 -0500
  4233. @@ -23,9 +23,10 @@
  4234.  
  4235.  #include <string>
  4236.  #include "texture.h"
  4237. +#include "fpmath.h"
  4238.  
  4239. -void display_text_file(const std::string& file, const std::string& surface, float scroll_speed);
  4240. -void display_text_file(const std::string& file, Surface* surface, float scroll_speed);
  4241. +void display_text_file(const std::string& file, const std::string& surface, fp scroll_speed);
  4242. +void display_text_file(const std::string& file, Surface* surface, fp scroll_speed);
  4243.  
  4244.  /* Kinds of texts. */
  4245.  enum {
  4246. diff -Naur supertux-0.1.3/src.bak/texture.cpp supertux-0.1.3/src/texture.cpp
  4247. --- supertux-0.1.3/src.bak/texture.cpp  2014-12-06 18:00:57.000000000 -0500
  4248. +++ supertux-0.1.3/src/texture.cpp  2014-12-06 18:04:19.000000000 -0500
  4249. @@ -207,7 +207,7 @@
  4250.  }
  4251.  
  4252.  void
  4253. -Surface::draw(float x, float y, Uint8 alpha, bool update)
  4254. +Surface::draw(int x, int y, Uint8 alpha, bool update)
  4255.  {
  4256.    if (impl)
  4257.    {
  4258. @@ -228,7 +228,7 @@
  4259.  }
  4260.  
  4261.  void
  4262. -Surface::draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update)
  4263. +Surface::draw_part(int sx, int sy, int x, int y, int w, int h,  Uint8 alpha, bool update)
  4264.  {
  4265.    if (impl)
  4266.    {
  4267. @@ -239,7 +239,7 @@
  4268.  }
  4269.  
  4270.  void
  4271. -Surface::draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update)
  4272. +Surface::draw_stretched(int x, int y, int w, int h, Uint8 alpha, bool update)
  4273.  {
  4274.    if (impl)
  4275.    {
  4276. @@ -538,10 +538,12 @@
  4277.  }
  4278.  
  4279.  int
  4280. -SurfaceOpenGL::draw(float x, float y, Uint8 alpha, bool update)
  4281. +SurfaceOpenGL::draw(int x, int y, Uint8 alpha, bool update)
  4282.  {
  4283.    float pw = power_of_two(w);
  4284.    float ph = power_of_two(h);
  4285. +  float xf = (float) x;
  4286. +  float yf = (float) y;
  4287.  
  4288.    glEnable(GL_TEXTURE_2D);
  4289.    glEnable(GL_BLEND);
  4290. @@ -553,12 +555,12 @@
  4291.  
  4292.    glBegin(GL_QUADS);
  4293.    glTexCoord2f(0, 0);
  4294. -  glVertex2f(x, y);
  4295. +  glVertex2f(xf, yf);
  4296.    glTexCoord2f((float)w / pw, 0);
  4297. -  glVertex2f((float)w+x, y);
  4298. -  glTexCoord2f((float)w / pw, (float)h / ph);  glVertex2f((float)w+x, (float)h+y);
  4299. +  glVertex2f((float)w+xf, yf);
  4300. +  glTexCoord2f((float)w / pw, (float)h / ph);  glVertex2f((float)w+xf, (float)h+yf);
  4301.    glTexCoord2f(0, (float)h / ph);
  4302. -  glVertex2f(x, (float)h+y);
  4303. +  glVertex2f(xf, (float)h+yf);
  4304.    glEnd();
  4305.  
  4306.    glDisable(GL_TEXTURE_2D);
  4307. @@ -599,10 +601,16 @@
  4308.  }
  4309.  
  4310.  int
  4311. -SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, bool update)
  4312. +SurfaceOpenGL::draw_part(int sx, int sy, int x, int y, int w, int h, Uint8 alpha, bool update)
  4313.  {
  4314.    float pw = power_of_two(int(this->w));
  4315.    float ph = power_of_two(int(this->h));
  4316. +  float sxf = (float) sx;
  4317. +  float syf = (float) sy;
  4318. +  float xf = (float) x;
  4319. +  float yf = (float) y;
  4320. +  float wf = (float) w;
  4321. +  float hf = (float) h;
  4322.  
  4323.    glBindTexture(GL_TEXTURE_2D, gl_texture);
  4324.  
  4325. @@ -615,14 +623,14 @@
  4326.  
  4327.  
  4328.    glBegin(GL_QUADS);
  4329. -  glTexCoord2f(sx / pw, sy / ph);
  4330. -  glVertex2f(x, y);
  4331. -  glTexCoord2f((float)(sx + w) / pw, sy / ph);
  4332. -  glVertex2f(w+x, y);
  4333. -  glTexCoord2f((sx+w) / pw, (sy+h) / ph);
  4334. -  glVertex2f(w +x, h+y);
  4335. -  glTexCoord2f(sx / pw, (float)(sy+h) / ph);
  4336. -  glVertex2f(x, h+y);
  4337. +  glTexCoord2f(sxf / pw, syf / ph);
  4338. +  glVertex2f(xf, yf);
  4339. +  glTexCoord2f((float)(sxf + wf) / pw, syf / ph);
  4340. +  glVertex2f(wf+xf, yf);
  4341. +  glTexCoord2f((sxf+wf) / pw, (syf+hf) / ph);
  4342. +  glVertex2f(wf+xf, hf+yf);
  4343. +  glTexCoord2f(sxf / pw, (float)(syf+hf) / ph);
  4344. +  glVertex2f(xf, hf+yf);
  4345.    glEnd();
  4346.  
  4347.    glDisable(GL_TEXTURE_2D);
  4348. @@ -633,10 +641,14 @@
  4349.  }
  4350.  
  4351.  int
  4352. -SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool update)
  4353. +SurfaceOpenGL::draw_stretched(int x, int y, int sw, int sh, Uint8 alpha, bool update)
  4354.  {
  4355.    float pw = power_of_two(int(this->w));
  4356.    float ph = power_of_two(int(this->h));
  4357. +  float xf = (float) x;
  4358. +  float yf = (float) y;
  4359. +  float swf = (float) sw;
  4360. +  float shf = (float) sh;
  4361.  
  4362.    glBindTexture(GL_TEXTURE_2D, gl_texture);
  4363.  
  4364. @@ -650,13 +662,14 @@
  4365.  
  4366.    glBegin(GL_QUADS);
  4367.    glTexCoord2f(0, 0);
  4368. -  glVertex2f(x, y);
  4369. +  glVertex2f(xf, yf);
  4370.    glTexCoord2f((float)w / pw, 0);
  4371. -  glVertex2f(sw+x, y);
  4372. -  glTexCoord2f((float)w / pw, (float)h / ph);  glVertex2f((float)sw+x, (float)sh+y);
  4373. -  glVertex2f(sw +x, sh+y);
  4374. +  glVertex2f(swf+xf, yf);
  4375. +  glTexCoord2f((float)w / pw, (float)h / ph);
  4376. +  glVertex2f(swf+xf, shf+yf);
  4377. +  glVertex2f(swf+xf, shf+yf);
  4378.    glTexCoord2f(0, (float)h / ph);
  4379. -  glVertex2f(x, sh+y);
  4380. +  glVertex2f(xf, shf+yf);
  4381.    glEnd();
  4382.  
  4383.    glDisable(GL_TEXTURE_2D);
  4384. @@ -690,12 +703,12 @@
  4385.  }
  4386.  
  4387.  int
  4388. -SurfaceSDL::draw(float x, float y, Uint8 alpha, bool update)
  4389. +SurfaceSDL::draw(int x, int y, Uint8 alpha, bool update)
  4390.  {
  4391.    SDL_Rect dest;
  4392.  
  4393. -  dest.x = (int)x;
  4394. -  dest.y = (int)y;
  4395. +  dest.x = x;
  4396. +  dest.y = y;
  4397.    dest.w = w;
  4398.    dest.h = h;
  4399.  
  4400. @@ -784,19 +797,19 @@
  4401.  }
  4402.  
  4403.  int
  4404. -SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, bool update)
  4405. +SurfaceSDL::draw_part(int sx, int sy, int x, int y, int w, int h, Uint8 alpha, bool update)
  4406.  {
  4407.    SDL_Rect src, dest;
  4408.  
  4409. -  src.x = (int)sx;
  4410. -  src.y = (int)sy;
  4411. -  src.w = (int)w;
  4412. -  src.h = (int)h;
  4413. -
  4414. -  dest.x = (int)x;
  4415. -  dest.y = (int)y;
  4416. -  dest.w = (int)w;
  4417. -  dest.h = (int)h;
  4418. +  src.x = sx;
  4419. +  src.y = sy;
  4420. +  src.w = w;
  4421. +  src.h = h;
  4422. +
  4423. +  dest.x = x;
  4424. +  dest.y = y;
  4425. +  dest.w = w;
  4426. +  dest.h = h;
  4427.  
  4428.    if(alpha != 255)
  4429.      {
  4430. @@ -836,14 +849,14 @@
  4431.  }
  4432.  
  4433.  int
  4434. -SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool update)
  4435. +SurfaceSDL::draw_stretched(int x, int y, int sw, int sh, Uint8 alpha, bool update)
  4436.  {
  4437.    SDL_Rect dest;
  4438.  
  4439. -  dest.x = (int)x;
  4440. -  dest.y = (int)y;
  4441. -  dest.w = (int)sw;
  4442. -  dest.h = (int)sh;
  4443. +  dest.x = x;
  4444. +  dest.y = y;
  4445. +  dest.w = sw;
  4446. +  dest.h = sh;
  4447.  
  4448.    if(alpha != 255)
  4449.      SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
  4450. diff -Naur supertux-0.1.3/src.bak/texture.h supertux-0.1.3/src/texture.h
  4451. --- supertux-0.1.3/src.bak/texture.h    2014-12-06 18:00:57.000000000 -0500
  4452. +++ supertux-0.1.3/src/texture.h    2014-12-06 18:04:19.000000000 -0500
  4453. @@ -87,10 +87,10 @@
  4454.    /** Reload the surface, which is necesarry in case of a mode swich */
  4455.    void reload();
  4456.  
  4457. -  void draw(float x, float y, Uint8 alpha = 255, bool update = false);
  4458. +  void draw(int x, int y, Uint8 alpha = 255, bool update = false);
  4459.    void draw_bg(Uint8 alpha = 255, bool update = false);
  4460. -  void draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha = 255, bool update = false);
  4461. -  void draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update = false);
  4462. +  void draw_part(int sx, int sy, int x, int y, int w, int h,  Uint8 alpha = 255, bool update = false);
  4463. +  void draw_stretched(int x, int y, int w, int h, Uint8 alpha, bool update = false);
  4464.    void resize(int w_, int h_);
  4465.  };
  4466.  
  4467. @@ -110,10 +110,10 @@
  4468.    virtual ~SurfaceImpl();
  4469.    
  4470.    /** Return 0 on success, -2 if surface needs to be reloaded */
  4471. -  virtual int draw(float x, float y, Uint8 alpha, bool update) = 0;
  4472. +  virtual int draw(int x, int y, Uint8 alpha, bool update) = 0;
  4473.    virtual int draw_bg(Uint8 alpha, bool update) = 0;
  4474. -  virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update) = 0;
  4475. -  virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update) = 0;
  4476. +  virtual int draw_part(int sx, int sy, int x, int y, int w, int h,  Uint8 alpha, bool update) = 0;
  4477. +  virtual int draw_stretched(int x, int y, int w, int h, Uint8 alpha, bool update) = 0;
  4478.    int resize(int w_, int h_);
  4479.  
  4480.    SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
  4481. @@ -127,10 +127,10 @@
  4482.    SurfaceSDL(const std::string& file, int x, int y, int w, int h, int use_alpha);
  4483.    virtual ~SurfaceSDL();
  4484.  
  4485. -  int draw(float x, float y, Uint8 alpha, bool update);
  4486. +  int draw(int x, int y, Uint8 alpha, bool update);
  4487.    int draw_bg(Uint8 alpha, bool update);
  4488. -  int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update);
  4489. -  int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update);
  4490. +  int draw_part(int sx, int sy, int x, int y, int w, int h,  Uint8 alpha, bool update);
  4491. +  int draw_stretched(int x, int y, int w, int h, Uint8 alpha, bool update);
  4492.  };
  4493.  
  4494.  #ifndef NOOPENGL
  4495. @@ -145,10 +145,10 @@
  4496.    SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, int use_alpha);
  4497.    virtual ~SurfaceOpenGL();
  4498.  
  4499. -  int draw(float x, float y, Uint8 alpha, bool update);
  4500. +  int draw(int x, int y, Uint8 alpha, bool update);
  4501.    int draw_bg(Uint8 alpha, bool update);
  4502. -  int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update);
  4503. -  int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update);
  4504. +  int draw_part(int sx, int sy, int x, int y, int w, int h,  Uint8 alpha, bool update);
  4505. +  int draw_stretched(int x, int y, int w, int h, Uint8 alpha, bool update);
  4506.  
  4507.  private:
  4508.    void create_gl(SDL_Surface * surf, GLuint * tex);
  4509. diff -Naur supertux-0.1.3/src.bak/tile.cpp supertux-0.1.3/src/tile.cpp
  4510. --- supertux-0.1.3/src.bak/tile.cpp 2014-12-06 18:00:57.000000000 -0500
  4511. +++ supertux-0.1.3/src/tile.cpp 2014-12-06 18:04:19.000000000 -0500
  4512. @@ -184,7 +184,7 @@
  4513.  }
  4514.  
  4515.  void
  4516. -Tile::draw(float x, float y, unsigned int c, Uint8 alpha)
  4517. +Tile::draw(int x, int y, unsigned int c, Uint8 alpha)
  4518.  {
  4519.    if (c != 0)
  4520.      {
  4521. @@ -208,7 +208,7 @@
  4522.  }
  4523.  
  4524.  void
  4525. -Tile::draw_stretched(float x, float y, int w, int h, unsigned int c, Uint8 alpha)
  4526. +Tile::draw_stretched(int x, int y, int w, int h, unsigned int c, Uint8 alpha)
  4527.  {
  4528.    if (c != 0)
  4529.      {
  4530. diff -Naur supertux-0.1.3/src.bak/tile.h supertux-0.1.3/src/tile.h
  4531. --- supertux-0.1.3/src.bak/tile.h   2014-12-06 18:00:57.000000000 -0500
  4532. +++ supertux-0.1.3/src/tile.h   2014-12-06 18:04:19.000000000 -0500
  4533. @@ -80,8 +80,8 @@
  4534.    int anim_speed;
  4535.    
  4536.    /** Draw a tile on the screen: */
  4537. -  static void draw(float x, float y, unsigned int c, Uint8 alpha = 255);
  4538. -  static void draw_stretched(float x, float y, int w, int h, unsigned int c, Uint8 alpha = 255);
  4539. +  static void draw(int x, int y, unsigned int c, Uint8 alpha = 255);
  4540. +  static void draw_stretched(int x, int y, int w, int h, unsigned int c, Uint8 alpha = 255);
  4541.  };
  4542.  
  4543.  struct TileGroup
  4544. diff -Naur supertux-0.1.3/src.bak/title.cpp supertux-0.1.3/src/title.cpp
  4545. --- supertux-0.1.3/src.bak/title.cpp    2014-12-06 18:00:57.000000000 -0500
  4546. +++ supertux-0.1.3/src/title.cpp    2014-12-07 10:36:25.000000000 -0500
  4547. @@ -51,6 +51,7 @@
  4548.  #include "tile.h"
  4549.  #include "resources.h"
  4550.  #include "worldmap.h"
  4551. +#include "fpmath.h"
  4552.  #include "sound.h"
  4553.  
  4554.  static Surface* bkg_title;
  4555. @@ -187,7 +188,7 @@
  4556.    bkg_title->draw_bg();
  4557.  }
  4558.  
  4559. -void draw_demo(GameSession* session, double frame_ratio)
  4560. +void draw_demo(GameSession* session, fp frame_ratio)
  4561.  {
  4562.    World* world  = session->get_world();
  4563.    World::set_current(world);
  4564. @@ -213,14 +214,14 @@
  4565.      }
  4566.  
  4567.    // Wrap around at the end of the level back to the beginnig
  4568. -  if((plevel->width * 32) - 320 < tux->base.x)
  4569. +  if(int2fp(plevel->width * 32 - 320) < tux->base.x)
  4570.      {
  4571.        tux->level_begin();
  4572.        scroll_x = 0;
  4573.      }
  4574.  
  4575.    tux->can_jump = true;
  4576. -  float last_tux_x_pos = tux->base.x;
  4577. +  fp last_tux_x_pos = tux->base.x;
  4578.    world->action(frame_ratio);
  4579.    
  4580.  
  4581. @@ -282,9 +283,9 @@
  4582.          update_time = last_update_time = st_get_ticks();
  4583.  
  4584.        // Calculate the movement-factor
  4585. -      double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
  4586. -      if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
  4587. -        frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
  4588. +      fp frame_ratio = (int2fp(update_time-last_update_time))/(FRAME_RATE);
  4589. +      if(frame_ratio > FP_FRAME_RATIO_LIMIT) /* Quick hack to correct the unprecise CPU clocks a little bit. */
  4590. +        frame_ratio = FP_FRAME_RATIO_LIMIT + fpmul((frame_ratio - FP_FRAME_RATIO_LIMIT), FP_FRAME_RATIO_CORR);
  4591.        /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */
  4592.        frame_ratio /= 2;
  4593.  
  4594. @@ -357,7 +358,7 @@
  4595.                    menu_song  = music_manager->load_music(datadir + "/music/credits.mod");
  4596.                    music_manager->halt_music();
  4597.                    music_manager->play_music(menu_song,0);
  4598. -                  display_text_file("CREDITS", bkg_title, SCROLL_SPEED_CREDITS);
  4599. +                  display_text_file("CREDITS", bkg_title, FP_SCROLL_SPEED_CREDITS);
  4600.                    music_manager->halt_music();
  4601.                    menu_song = music_manager->load_music(datadir + "/music/theme.mod");
  4602.                    music_manager->play_music(menu_song);
  4603. diff -Naur supertux-0.1.3/src.bak/type.h supertux-0.1.3/src/type.h
  4604. --- supertux-0.1.3/src.bak/type.h   2014-12-06 18:00:57.000000000 -0500
  4605. +++ supertux-0.1.3/src/type.h   2014-12-06 18:04:19.000000000 -0500
  4606. @@ -24,17 +24,18 @@
  4607.  #include <string>
  4608.  #include "SDL.h"
  4609.  #include "scene.h"
  4610. +#include "fpmath.h"
  4611.  
  4612.  /* 'Base' type for game objects */
  4613.  
  4614.  struct base_type
  4615.  {
  4616. -  float x;
  4617. -  float y;
  4618. -  float xm;
  4619. -  float ym;
  4620. -  float width;
  4621. -  float height;
  4622. +  fp x;
  4623. +  fp y;
  4624. +  fp xm;
  4625. +  fp ym;
  4626. +  fp width;
  4627. +  fp height;
  4628.  };
  4629.  
  4630.  
  4631. @@ -45,27 +46,28 @@
  4632.  public:
  4633.    GameObject() {};
  4634.    virtual ~GameObject() {};
  4635. -  virtual void action(double frame_ratio) = 0;
  4636. +  virtual void action(fp frame_ratio) = 0;
  4637.    virtual void draw() = 0;
  4638.    virtual std::string type() = 0;
  4639.    /* Draw ignoring the scroll_x value. FIXME: Hack? Should be discussed. @tobgle*/
  4640. -  void draw_on_screen(float x = -1, float y = -1)
  4641. +  void draw_on_screen(fp x = int2fp(-1), fp y = int2fp(-1))
  4642.    {
  4643.      base_type btmp = base;
  4644. -    if(x != -1 || y != -1)
  4645. +    if(x != int2fp(-1) || y != int2fp(-1))
  4646.      {
  4647.        btmp = base;
  4648. -      if(x != -1)
  4649. +      if(x != int2fp(-1))
  4650.          base.x = x;
  4651. -      if(y != -1)
  4652. +      if(y != int2fp(-1))
  4653.          base.y = y;
  4654.      }
  4655. -    float tmp = scroll_x;
  4656. -    scroll_x = 0; draw();
  4657. +    fp tmp = scroll_x;
  4658. +    scroll_x = 0;
  4659. +    draw();
  4660.      scroll_x = tmp;
  4661.      base = btmp;
  4662.    };
  4663. -void move_to(float x, float y) { base.x = x; base.y = y; };
  4664. +void move_to(fp x, fp y) { base.x = x; base.y = y; };
  4665.  
  4666.    base_type base;
  4667.    base_type old_base;
  4668. diff -Naur supertux-0.1.3/src.bak/world.cpp supertux-0.1.3/src/world.cpp
  4669. --- supertux-0.1.3/src.bak/world.cpp    2014-12-06 18:00:57.000000000 -0500
  4670. +++ supertux-0.1.3/src/world.cpp    2014-12-07 10:46:53.000000000 -0500
  4671. @@ -32,6 +32,7 @@
  4672.  #include "level.h"
  4673.  #include "tile.h"
  4674.  #include "resources.h"
  4675. +#include "fpmath.h"
  4676.  
  4677.  Surface* img_distro[4];
  4678.  
  4679. @@ -95,8 +96,8 @@
  4680.      case PlayerStatus::GROWUP_BONUS:
  4681.        // FIXME: Move this to Player class
  4682.        tux.size = BIG;
  4683. -      tux.base.height = 64;
  4684. -      tux.base.y -= 32;
  4685. +      tux.base.height = int2fp(64);
  4686. +      tux.base.y -= int2fp(32);
  4687.        break;
  4688.      }
  4689.  }
  4690. @@ -151,7 +152,7 @@
  4691.         i != level->badguy_data.end();
  4692.         ++i)
  4693.      {
  4694. -      add_bad_guy(i->x, i->y, i->kind, i->stay_on_platform);
  4695. +      add_bad_guy(int2fp(i->x), int2fp(i->y), i->kind, i->stay_on_platform);
  4696.      }
  4697.  }
  4698.  
  4699. @@ -176,11 +177,14 @@
  4700.  World::draw()
  4701.  {
  4702.    int y,x;
  4703. +  int scroll_xi = fp2int(scroll_x);
  4704.  
  4705.    /* Draw the real background */
  4706.    if(level->img_bkgd)
  4707.      {
  4708. -      int s = (int)((float)scroll_x * ((float)level->bkgd_speed/100.0f)) % screen->w;
  4709. +      // overflow occurs if real fp calculation is done, so truncate to int first:
  4710. +      //int s = fp2int(scroll_x * level->bkgd_speed / 100) % screen->w;
  4711. +      int s = (scroll_xi * level->bkgd_speed / 100) % screen->w;
  4712.        level->img_bkgd->draw_part(s, 0,0,0,level->img_bkgd->w - s, level->img_bkgd->h);
  4713.        level->img_bkgd->draw_part(0, 0,screen->w - s ,0,s,level->img_bkgd->h);
  4714.      }
  4715. @@ -201,8 +205,8 @@
  4716.      {
  4717.        for (x = 0; x < 21; ++x)
  4718.          {
  4719. -          Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
  4720. -                     level->bg_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
  4721. +          Tile::draw(32*x - (scroll_xi % 32), y * 32,
  4722. +                     level->bg_tiles[y][x + (scroll_xi / 32)]);
  4723.          }
  4724.      }
  4725.  
  4726. @@ -212,8 +216,8 @@
  4727.      {
  4728.        for (x = 0; x < 21; ++x)
  4729.          {
  4730. -          Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
  4731. -                     level->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
  4732. +          Tile::draw(32*x - (scroll_xi % 32), y * 32,
  4733. +                     level->ia_tiles[y][x + (scroll_xi / 32)]);
  4734.          }
  4735.      }
  4736.  
  4737. @@ -246,8 +250,8 @@
  4738.      {
  4739.        for (x = 0; x < 21; ++x)
  4740.          {
  4741. -          Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
  4742. -                     level->fg_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
  4743. +          Tile::draw(32*x - (scroll_xi % 32), y * 32,
  4744. +                     level->fg_tiles[y][x + (scroll_xi / 32)]);
  4745.          }
  4746.      }
  4747.  
  4748. @@ -261,7 +265,7 @@
  4749.  }
  4750.  
  4751.  void
  4752. -World::action(double frame_ratio)
  4753. +World::action(fp frame_ratio)
  4754.  {
  4755.    tux.action(frame_ratio);
  4756.    tux.check_bounds(level->back_scrolling, (bool)level->hor_autoscroll_speed);
  4757. @@ -325,15 +329,15 @@
  4758.  #define CHANGE_DIR_SCROLL_SPEED 2000
  4759.  
  4760.  /* This functions takes cares of the scrolling */
  4761. -void World::scrolling(double frame_ratio)
  4762. +void World::scrolling(fp frame_ratio)
  4763.  {
  4764.    if(level->hor_autoscroll_speed)
  4765.      {
  4766. -    scroll_x += level->hor_autoscroll_speed * frame_ratio;
  4767. +    scroll_x += fpmul(level->hor_autoscroll_speed, frame_ratio);
  4768.      return;
  4769.      }
  4770.  
  4771. -  int tux_pos_x = (int)(tux.base.x + (tux.base.width/2));
  4772. +  int tux_pos_x = fp2int(tux.base.x + (tux.base.width/2));
  4773.  
  4774.    if (level->back_scrolling || debug_mode)
  4775.    {
  4776. @@ -342,53 +346,54 @@
  4777.  
  4778.      if(scrolling_timer.check())
  4779.      {
  4780. -      float final_scroll_x;
  4781. +      fp final_scroll_x;
  4782.        if (tux.physic.get_velocity_x() > 0)
  4783. -        final_scroll_x = tux_pos_x - (screen->w - X_SPACE);
  4784. +        final_scroll_x = int2fp(tux_pos_x - (screen->w - X_SPACE));
  4785.        else if (tux.physic.get_velocity_x() < 0)
  4786. -        final_scroll_x = tux_pos_x - X_SPACE;
  4787. +        final_scroll_x = int2fp(tux_pos_x - X_SPACE);
  4788.        else
  4789.        {
  4790.          if (tux.dir == RIGHT)
  4791. -          final_scroll_x = tux_pos_x - (screen->w - X_SPACE);
  4792. +          final_scroll_x = int2fp(tux_pos_x - (screen->w - X_SPACE));
  4793.          else if (tux.dir == LEFT && level->back_scrolling)
  4794. -          final_scroll_x = tux_pos_x - X_SPACE;
  4795. +          final_scroll_x = int2fp(tux_pos_x - X_SPACE);
  4796.        }
  4797.  
  4798. -      scroll_x +=   (final_scroll_x - scroll_x)
  4799. -                  / (frame_ratio * (CHANGE_DIR_SCROLL_SPEED / 100))
  4800. -                  + (tux.physic.get_velocity_x() * frame_ratio + tux.physic.get_acceleration_x() * frame_ratio * frame_ratio);
  4801. +      scroll_x += fpdiv( (final_scroll_x - scroll_x),
  4802. +                         (frame_ratio * (CHANGE_DIR_SCROLL_SPEED / 100)) )
  4803. +                  + (fpmul(tux.physic.get_velocity_x(), frame_ratio) +
  4804. +                     fpmul(tux.physic.get_acceleration_x(), fpmul(frame_ratio, frame_ratio)));
  4805.        // std::cerr << tux_pos_x << " " << final_scroll_x << " " << scroll_x << std::endl;
  4806.  
  4807.      }
  4808.      else
  4809.      {
  4810. -      if (tux.physic.get_velocity_x() > 0 && scroll_x < tux_pos_x - (screen->w - X_SPACE))
  4811. -        scroll_x = tux_pos_x - (screen->w - X_SPACE);
  4812. -      else if (tux.physic.get_velocity_x() < 0 && scroll_x > tux_pos_x - X_SPACE && level->back_scrolling)
  4813. -        scroll_x = tux_pos_x - X_SPACE;
  4814. +      if (tux.physic.get_velocity_x() > 0 && scroll_x < int2fp(tux_pos_x - (screen->w - X_SPACE)))
  4815. +        scroll_x = int2fp(tux_pos_x - (screen->w - X_SPACE));
  4816. +      else if (tux.physic.get_velocity_x() < 0 && scroll_x > int2fp(tux_pos_x - X_SPACE) && level->back_scrolling)
  4817. +        scroll_x = int2fp(tux_pos_x - X_SPACE);
  4818.        else
  4819.        {
  4820. -        if (tux.dir == RIGHT && scroll_x < tux_pos_x - (screen->w - X_SPACE))
  4821. -            scroll_x = tux_pos_x - (screen->w - X_SPACE);
  4822. -        else if (tux.dir == LEFT && scroll_x > tux_pos_x - X_SPACE && level->back_scrolling)
  4823. -            scroll_x = tux_pos_x - X_SPACE;
  4824. +        if (tux.dir == RIGHT && scroll_x < int2fp(tux_pos_x - (screen->w - X_SPACE)))
  4825. +            scroll_x = int2fp(tux_pos_x - (screen->w - X_SPACE));
  4826. +        else if (tux.dir == LEFT && scroll_x > int2fp(tux_pos_x - X_SPACE) && level->back_scrolling)
  4827. +            scroll_x = int2fp(tux_pos_x - X_SPACE);
  4828.        }
  4829.      }
  4830.    }
  4831.  
  4832.    else /*no debug*/
  4833.    {
  4834. -    if (tux.physic.get_velocity_x() > 0 && scroll_x < tux_pos_x - (screen->w - X_SPACE))
  4835. -      scroll_x = tux_pos_x - (screen->w - X_SPACE);
  4836. -    else if (tux.physic.get_velocity_x() < 0 && scroll_x > tux_pos_x - X_SPACE && level->back_scrolling)
  4837. -      scroll_x = tux_pos_x - X_SPACE;
  4838. +    if (tux.physic.get_velocity_x() > 0 && scroll_x < int2fp(tux_pos_x - (screen->w - X_SPACE)))
  4839. +      scroll_x = int2fp(tux_pos_x - (screen->w - X_SPACE));
  4840. +    else if (tux.physic.get_velocity_x() < 0 && scroll_x > int2fp(tux_pos_x - X_SPACE) && level->back_scrolling)
  4841. +      scroll_x = int2fp(tux_pos_x - X_SPACE);
  4842.      else
  4843.      {
  4844. -      if (tux.dir == RIGHT && scroll_x < tux_pos_x - (screen->w - X_SPACE))
  4845. -          scroll_x = tux_pos_x - (screen->w - X_SPACE);
  4846. -      else if (tux.dir == LEFT && scroll_x > tux_pos_x - X_SPACE && level->back_scrolling)
  4847. -          scroll_x = tux_pos_x - X_SPACE;
  4848. +      if (tux.dir == RIGHT && scroll_x < int2fp(tux_pos_x - (screen->w - X_SPACE)))
  4849. +          scroll_x = int2fp(tux_pos_x - (screen->w - X_SPACE));
  4850. +      else if (tux.dir == LEFT && scroll_x > int2fp(tux_pos_x - X_SPACE) && level->back_scrolling)
  4851. +          scroll_x = int2fp(tux_pos_x - X_SPACE);
  4852.      }
  4853.  
  4854.    }
  4855. @@ -397,11 +402,13 @@
  4856.    if(scroll_x < 0)
  4857.      scroll_x = 0;
  4858.  #ifndef RES320X240
  4859. +  if(scroll_x > int2fp(level->width * 32 - screen->w))
  4860. +    scroll_x = int2fp(level->width * 32 - screen->w);
  4861.    if(scroll_x > level->width * 32 - screen->w)
  4862.      scroll_x = level->width * 32 - screen->w;
  4863.  #else
  4864. -  if(scroll_x > level->width * 32 - 640)
  4865. -    scroll_x = level->width * 32 - 640;
  4866. +  if(scroll_x > int2fp(level->width * 32 - 640))
  4867. +    scroll_x = int2fp(level->width * 32 - 640);
  4868.  #endif
  4869.  }
  4870.  
  4871. @@ -492,7 +499,7 @@
  4872.  }
  4873.  
  4874.  void
  4875. -World::add_score(float x, float y, int s)
  4876. +World::add_score(fp x, fp y, int s)
  4877.  {
  4878.  #ifdef RES320X240
  4879.    x=x/2;
  4880. @@ -506,7 +513,7 @@
  4881.  }
  4882.  
  4883.  void
  4884. -World::add_bouncy_distro(float x, float y)
  4885. +World::add_bouncy_distro(fp x, fp y)
  4886.  {
  4887.    BouncyDistro* new_bouncy_distro = new BouncyDistro();
  4888.    new_bouncy_distro->init(x,y);
  4889. @@ -514,17 +521,17 @@
  4890.  }
  4891.  
  4892.  void
  4893. -World::add_broken_brick(Tile* tile, float x, float y)
  4894. +World::add_broken_brick(Tile* tile, fp x, fp y)
  4895.  {
  4896. -  add_broken_brick_piece(tile, x, y, -1, -4);
  4897. -  add_broken_brick_piece(tile, x, y + 16, -1.5, -3);
  4898. +  add_broken_brick_piece(tile, x, y, int2fp(-1), int2fp(-4));
  4899. +  add_broken_brick_piece(tile, x, y + int2fp(16), -FP_BROKEN_PIECE_SPEED, int2fp(-3));
  4900.  
  4901. -  add_broken_brick_piece(tile, x + 16, y, 1, -4);
  4902. -  add_broken_brick_piece(tile, x + 16, y + 16, 1.5, -3);
  4903. +  add_broken_brick_piece(tile, x + int2fp(16), y, int2fp(1), int2fp(-4));
  4904. +  add_broken_brick_piece(tile, x + int2fp(16), y + int2fp(16), FP_BROKEN_PIECE_SPEED, int2fp(-3));
  4905.  }
  4906.  
  4907.  void
  4908. -World::add_broken_brick_piece(Tile* tile, float x, float y, float xm, float ym)
  4909. +World::add_broken_brick_piece(Tile* tile, fp x, fp y, fp xm, fp ym)
  4910.  {
  4911.    BrokenBrick* new_broken_brick = new BrokenBrick();
  4912.    new_broken_brick->init(tile, x, y, xm, ym);
  4913. @@ -532,7 +539,7 @@
  4914.  }
  4915.  
  4916.  void
  4917. -World::add_bouncy_brick(float x, float y)
  4918. +World::add_bouncy_brick(fp x, fp y)
  4919.  {
  4920.    BouncyBrick* new_bouncy_brick = new BouncyBrick();
  4921.    new_bouncy_brick->init(x,y);
  4922. @@ -540,7 +547,7 @@
  4923.  }
  4924.  
  4925.  BadGuy*
  4926. -World::add_bad_guy(float x, float y, BadGuyKind kind, bool stay_on_platform)
  4927. +World::add_bad_guy(fp x, fp y, BadGuyKind kind, bool stay_on_platform)
  4928.  {
  4929.    BadGuy* badguy = new BadGuy(x,y,kind, stay_on_platform);
  4930.    bad_guys.push_back(badguy);
  4931. @@ -548,7 +555,7 @@
  4932.  }
  4933.  
  4934.  void
  4935. -World::add_upgrade(float x, float y, Direction dir, UpgradeKind kind)
  4936. +World::add_upgrade(fp x, fp y, Direction dir, UpgradeKind kind)
  4937.  {
  4938.    Upgrade new_upgrade;
  4939.    new_upgrade.init(x,y,dir,kind);
  4940. @@ -556,7 +563,7 @@
  4941.  }
  4942.  
  4943.  void
  4944. -World::add_bullet(float x, float y, float xm, Direction dir)
  4945. +World::add_bullet(fp x, fp y, fp xm, Direction dir)
  4946.  {
  4947.    if(bullets.size() > MAX_BULLETS-1)
  4948.      return;
  4949. @@ -599,18 +606,20 @@
  4950.  
  4951.  /* Break a brick: */
  4952.  void
  4953. -World::trybreakbrick(float x, float y, bool small, Direction col_side)
  4954. +World::trybreakbrick(fp x, fp y, bool small, Direction col_side)
  4955.  {
  4956.    Level* plevel = get_level();
  4957. +  int xx = fp2int(x);
  4958. +  int yy = fp2int(y);
  4959.    
  4960. -  Tile* tile = gettile(x, y);
  4961. +  Tile* tile = gettile(xx, yy);
  4962.    if (tile->brick)
  4963.      {
  4964.        if (tile->data > 0)
  4965.          {
  4966.            /* Get a distro from it: */
  4967. -          add_bouncy_distro(((int)(x + 1) / 32) * 32,
  4968. -                                  (int)(y / 32) * 32);
  4969. +          add_bouncy_distro( int2fp(((xx + 1) / 32) * 32),
  4970. +                             int2fp((yy / 32) * 32));
  4971.  
  4972.            // TODO: don't handle this in a global way but per-tile...
  4973.            if (!counting_distros)
  4974. @@ -626,7 +635,7 @@
  4975.            if (distro_counter <= 0)
  4976.              {
  4977.                counting_distros = false;
  4978. -              plevel->change(x, y, TM_IA, tile->next_tile);
  4979. +              plevel->change(xx, yy, TM_IA, tile->next_tile);
  4980.              }
  4981.  #ifndef GP2X
  4982.            play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
  4983. @@ -639,12 +648,12 @@
  4984.        else if (!small)
  4985.          {
  4986.            /* Get rid of it: */
  4987. -          plevel->change(x, y, TM_IA, tile->next_tile);
  4988. +          plevel->change(xx, yy, TM_IA, tile->next_tile);
  4989.            
  4990.            /* Replace it with broken bits: */
  4991.            add_broken_brick(tile,
  4992. -                                 ((int)(x + 1) / 32) * 32,
  4993. -                                 (int)(y / 32) * 32);
  4994. +                                 int2fp(((xx + 1) / 32) * 32),
  4995. +                                 int2fp((yy / 32) * 32));
  4996.  
  4997.            /* Get some score: */
  4998.  #ifndef GP2X
  4999. @@ -661,9 +670,12 @@
  5000.  
  5001.  /* Empty a box: */
  5002.  void
  5003. -World::tryemptybox(float x, float y, Direction col_side)
  5004. +World::tryemptybox(fp x, fp y, Direction col_side)
  5005.  {
  5006. -  Tile* tile = gettile(x,y);
  5007. +  int xx = fp2int(x);
  5008. +  int yy = fp2int(y);
  5009. +
  5010. +  Tile* tile = gettile(xx,yy);
  5011.    if (!tile->fullbox)
  5012.      return;
  5013.  
  5014. @@ -673,12 +685,12 @@
  5015.    else
  5016.      col_side = LEFT;
  5017.  
  5018. -  int posx = ((int)(x+1) / 32) * 32;
  5019. -  int posy = (int)(y/32) * 32 - 32;
  5020. +  int posx = ((xx+1) / 32) * 32;
  5021. +  int posy = (yy/32) * 32 - 32;
  5022.    switch(tile->data)
  5023.      {
  5024.      case 1: // Box with a distro!
  5025. -      add_bouncy_distro(posx, posy);
  5026. +      add_bouncy_distro(int2fp(posx), int2fp(posy));
  5027.  #ifndef GP2X
  5028.        play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
  5029.  #else
  5030. @@ -690,9 +702,9 @@
  5031.  
  5032.      case 2: // Add an upgrade!
  5033.        if (tux.size == SMALL)     /* Tux is small, add mints! */
  5034. -        add_upgrade(posx, posy, col_side, UPGRADE_GROWUP);
  5035. +        add_upgrade(int2fp(posx), int2fp(posy), col_side, UPGRADE_GROWUP);
  5036.        else     /* Tux is big, add an iceflower: */
  5037. -        add_upgrade(posx, posy, col_side, UPGRADE_ICEFLOWER);
  5038. +        add_upgrade(int2fp(posx), int2fp(posy), col_side, UPGRADE_ICEFLOWER);
  5039.  #ifndef GP2X
  5040.        play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
  5041.  #else
  5042. @@ -701,28 +713,31 @@
  5043.        break;
  5044.  
  5045.      case 3: // Add a golden herring
  5046. -      add_upgrade(posx, posy, col_side, UPGRADE_HERRING);
  5047. +      add_upgrade(int2fp(posx), int2fp(posy), col_side, UPGRADE_HERRING);
  5048.        break;
  5049.  
  5050.      case 4: // Add a 1up extra
  5051. -      add_upgrade(posx, posy, col_side, UPGRADE_1UP);
  5052. +      add_upgrade(int2fp(posx), int2fp(posy), col_side, UPGRADE_1UP);
  5053.        break;
  5054.      default:
  5055.        break;
  5056.      }
  5057.  
  5058.    /* Empty the box: */
  5059. -  level->change(x, y, TM_IA, tile->next_tile);
  5060. +  level->change(xx, yy, TM_IA, tile->next_tile);
  5061.  }
  5062.  
  5063.  /* Try to grab a distro: */
  5064.  void
  5065. -World::trygrabdistro(float x, float y, int bounciness)
  5066. +World::trygrabdistro(fp x, fp y, int bounciness)
  5067.  {
  5068. -  Tile* tile = gettile(x, y);
  5069. +  int xx = fp2int(x);
  5070. +  int yy = fp2int(y);
  5071. +
  5072. +  Tile* tile = gettile(xx, yy);
  5073.    if (tile && tile->distro)
  5074.      {
  5075. -      level->change(x, y, TM_IA, tile->next_tile);
  5076. +      level->change(xx, yy, TM_IA, tile->next_tile);
  5077.  #ifndef GP2X
  5078.        play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
  5079.  #else
  5080. @@ -731,8 +746,8 @@
  5081.  
  5082.        if (bounciness == BOUNCE)
  5083.          {
  5084. -          add_bouncy_distro(((int)(x + 1) / 32) * 32,
  5085. -                                  (int)(y / 32) * 32);
  5086. +          add_bouncy_distro(int2fp(((xx + 1) / 32) * 32),
  5087. +                            int2fp((yy / 32) * 32));
  5088.          }
  5089.  
  5090.        player_status.score = player_status.score + SCORE_DISTRO;
  5091. @@ -742,13 +757,13 @@
  5092.  
  5093.  /* Try to bump a bad guy from below: */
  5094.  void
  5095. -World::trybumpbadguy(float x, float y)
  5096. +World::trybumpbadguy(fp x, fp y)
  5097.  {
  5098.    // Bad guys:
  5099.    for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i)
  5100.      {
  5101. -      if ((*i)->base.x >= x - 32 && (*i)->base.x <= x + 32 &&
  5102. -          (*i)->base.y >= y - 16 && (*i)->base.y <= y + 16)
  5103. +      if ((*i)->base.x >= x - int2fp(32) && (*i)->base.x <= x + int2fp(32) &&
  5104. +          (*i)->base.y >= y - int2fp(16) && (*i)->base.y <= y + int2fp(16))
  5105.          {
  5106.            (*i)->collision(&tux, CO_PLAYER, COLLISION_BUMP);
  5107.          }
  5108. @@ -757,9 +772,9 @@
  5109.    // Upgrades:
  5110.    for (unsigned int i = 0; i < upgrades.size(); i++)
  5111.      {
  5112. -      if (upgrades[i].base.height == 32 &&
  5113. -          upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 &&
  5114. -          upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16)
  5115. +      if (upgrades[i].base.height == int2fp(32) &&
  5116. +          upgrades[i].base.x >= x - int2fp(32) && upgrades[i].base.x <= x + int2fp(32) &&
  5117. +          upgrades[i].base.y >= y - int2fp(16) && upgrades[i].base.y <= y + int2fp(16))
  5118.          {
  5119.            upgrades[i].collision(&tux, CO_PLAYER, COLLISION_BUMP);
  5120.          }
  5121. diff -Naur supertux-0.1.3/src.bak/world.h supertux-0.1.3/src/world.h
  5122. --- supertux-0.1.3/src.bak/world.h  2014-12-06 18:00:57.000000000 -0500
  5123. +++ supertux-0.1.3/src/world.h  2014-12-06 18:04:19.000000000 -0500
  5124. @@ -30,6 +30,7 @@
  5125.  #include "badguy.h"
  5126.  #include "particlesystem.h"
  5127.  #include "gameobjs.h"
  5128. +#include "fpmath.h"
  5129.  
  5130.  class Level;
  5131.  
  5132. @@ -77,8 +78,8 @@
  5133.    void set_defaults();
  5134.  
  5135.    void draw();
  5136. -  void action(double frame_ratio);
  5137. -  void scrolling(double frame_ratio);   // camera scrolling
  5138. +  void action(fp frame_ratio);
  5139. +  void scrolling(fp frame_ratio);   // camera scrolling
  5140.  
  5141.    void play_music(int musictype);
  5142.    int get_music_type();
  5143. @@ -92,29 +93,29 @@
  5144.    void activate_particle_systems();
  5145.    void activate_bad_guys();
  5146.  
  5147. -  void add_score(float x, float y, int s);
  5148. -  void add_bouncy_distro(float x, float y);
  5149. -  void add_broken_brick(Tile* tile, float x, float y);
  5150. -  void add_broken_brick_piece(Tile* tile, float x, float y, float xm, float ym);
  5151. -  void add_bouncy_brick(float x, float y);
  5152. +  void add_score(fp x, fp y, int s);
  5153. +  void add_bouncy_distro(fp x, fp y);
  5154. +  void add_broken_brick(Tile* tile, fp x, fp y);
  5155. +  void add_broken_brick_piece(Tile* tile, fp x, fp y, fp xm, fp ym);
  5156. +  void add_bouncy_brick(fp x, fp y);
  5157.  
  5158. -  BadGuy* add_bad_guy(float x, float y, BadGuyKind kind, bool stay_on_platform = false);
  5159. +  BadGuy* add_bad_guy(fp x, fp y, BadGuyKind kind, bool stay_on_platform = false);
  5160.  
  5161. -  void add_upgrade(float x, float y, Direction dir, UpgradeKind kind);
  5162. -  void add_bullet(float x, float y, float xm, Direction dir);
  5163. +  void add_upgrade(fp x, fp y, Direction dir, UpgradeKind kind);
  5164. +  void add_bullet(fp x, fp y, fp xm, Direction dir);
  5165.  
  5166.    /** Try to grab the coin at the given coordinates */
  5167. -  void trygrabdistro(float x, float y, int bounciness);
  5168. +  void trygrabdistro(fp x, fp y, int bounciness);
  5169.  
  5170.    /** Try to break the brick at the given coordinates */
  5171. -  void trybreakbrick(float x, float y, bool small, Direction col_side);
  5172. +  void trybreakbrick(fp x, fp y, bool small, Direction col_side);
  5173.  
  5174.    /** Try to get the content out of a bonus box, thus emptying it */
  5175. -  void tryemptybox(float x, float y, Direction col_side);
  5176. +  void tryemptybox(fp x, fp y, Direction col_side);
  5177.  
  5178.    /** Try to bumb a badguy that might we walking above Tux, thus shaking
  5179.        the tile which the badguy is walking on an killing him this way */
  5180. -  void trybumpbadguy(float x, float y);
  5181. +  void trybumpbadguy(fp x, fp y);
  5182.  
  5183.    /** Apply bonuses active in the player status, used to reactivate
  5184.        bonuses from former levels */
  5185. diff -Naur supertux-0.1.3/src.bak/worldmap.cpp supertux-0.1.3/src/worldmap.cpp
  5186. --- supertux-0.1.3/src.bak/worldmap.cpp 2014-12-06 18:00:57.000000000 -0500
  5187. +++ supertux-0.1.3/src/worldmap.cpp 2014-12-07 10:49:12.000000000 -0500
  5188. @@ -516,9 +516,17 @@
  5189.    /** get level's title */
  5190.    level->title = "<no title>";
  5191.  
  5192. -  FILE * fi;
  5193. +  char fname[1024];
  5194. +
  5195. +  strcpy(fname, (datadir +  "/levels/" + level->name).c_str());
  5196. +  if(!faccessible(fname)) {
  5197. +   strcat(fname, ".gz");
  5198. +  }
  5199. +
  5200. +  //FILE * fi;
  5201. +  gzFile fi;
  5202.    lisp_object_t* root_obj = 0;
  5203. -  fi = fopen((datadir +  "/levels/" + level->name).c_str(), "r");
  5204. +  fi = gzopen(fname, "r");
  5205.    if (fi == NULL)
  5206.    {
  5207.      perror((datadir +  "/levels/" + level->name).c_str());
  5208. @@ -526,7 +534,7 @@
  5209.    }
  5210.  
  5211.    lisp_stream_t stream;
  5212. -  lisp_stream_init_file (&stream, fi);
  5213. +  lisp_stream_init_gzfile (&stream, fi);
  5214.    root_obj = lisp_read (&stream);
  5215.  
  5216.    if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
  5217. @@ -542,7 +550,7 @@
  5218.  
  5219.    lisp_free(root_obj);
  5220.  
  5221. -  fclose(fi);
  5222. +  gzclose(fi);
  5223.  }
  5224.  
  5225.  void
  5226. @@ -791,10 +799,10 @@
  5227.                          music_manager->play_music(theme);
  5228.                          // Display final credits and go back to the main menu
  5229.                          display_text_file(level->extro_filename,
  5230. -                                          "/images/background/extro.jpg", SCROLL_SPEED_MESSAGE);
  5231. +                                          "/images/background/extro.jpg", FP_SCROLL_SPEED_MESSAGE);
  5232.             music_manager->play_music(credits,0);
  5233.             display_text_file("CREDITS",
  5234. -                                          "/images/background/oiltux.jpg", SCROLL_SPEED_CREDITS);
  5235. +                                          "/images/background/oiltux.jpg", FP_SCROLL_SPEED_CREDITS);
  5236.                          music_manager->play_music(theme);
  5237.                          quit = true;
  5238.                        }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement