diff --git a/apps/plugin.h b/apps/plugin.h
index b060104..2d8df6a 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -94,6 +94,7 @@ void* plugin_get_buffer(size_t *buffer_size);
 #include "ata_idle_notify.h"
 #include "settings_list.h"
 #include "timefuncs.h"
+#include "fixedpoint.h"

 #ifdef HAVE_ALBUMART
 #include "albumart.h"
diff --git a/apps/plugins/chopper.c b/apps/plugins/chopper.c
index f93f713..2387db0 100644
--- a/apps/plugins/chopper.c
+++ b/apps/plugins/chopper.c
@@ -171,41 +171,50 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define LEVEL_MODE_STEEP 1

 #if LCD_HEIGHT <= 64
-#define CYCLES 100
+#define REFERENCE_CYCLES 100
 static inline int SCALE(int x)
 {
     return x == 1 ? x : x >> 1;
 }
 #define SIZE 2
 #else
-#define CYCLES 60
+#define REFERENCE_CYCLES  60
 #define SCALE(x) (x)
 #define SIZE 1
 #endif

-/* in 10 milisecond (ticks) */
-#define CYCLETIME ((CYCLES*HZ)/1000)
-

 /* some fixed-point math for speed calculation
  * based on brickmania after r22882 */
-#define FIXED4(x)           ((x)<<4)
-#define FIXED4_MUL(x, y)    ((long long)((x)*(y))>>4)
-#define FIXED4_DIV(x, y)    (((x)<<4)/(y))
-#define INT4(x)             ((x)>>4)
+#define PRECISION           8
+#define FIXED4(x)           ((x)<<PRECISION)
+#define FIXED4_MUL(x, y)    fp_mul(x,y,PRECISION)
+#define FIXED4_DIV(x, y)    fp_div(x,y,PRECISION)
+#define INT4(x)             ((x)>>8)
+
+#if defined(SANSA_FUZE) || 1
+#define CHOPPER_SPEED_FACTOR 3
+#endif

+#ifndef CHOPPER_SPEED_FACTOR
+#define CHOPPER_SPEED_FACTOR 1
+#endif

+#define CYCLES (REFERENCE_CYCLES / CHOPPER_SPEED_FACTOR)

+/* in 10 milisecond (ticks) */
+#define CYCLETIME ((CYCLES*HZ)/1000)
 /*Chopper's local variables to track the terrain position etc*/
 static int chopCounter;
 static int iRotorOffset;
 static int iScreenX;
 static int iScreenY;
+static int iCameraPosX;
+/* the next for are 24.8 fixed point numbers */
 static int iPlayerPosX;
 static int iPlayerPosY;
-static int iCameraPosX;
 static unsigned iPlayerSpeedX;
-static unsigned iPlayerSpeedY;
+static int iPlayerSpeedY;
 static int iLastBlockPlacedPosX;
 static int iGravityTimerCountdown;
 static int iPlayerAlive;
@@ -380,7 +389,7 @@ int chopUpdateTerrainRecycling(struct CTerrain *ter)
     while(i < ter->iNodesCount)
     {

-        if( iCameraPosX > ter->mNodes[i].x)
+        if( INT4(iCameraPosX) > ter->mNodes[i].x)
         {

             chopTerrainNodeDeleteAndShift(ter,i);
@@ -546,7 +555,7 @@ static int chopBlockCollideWithPlayer(struct CBlock *mBlock)

 static int chopBlockOffscreen(struct CBlock *mBlock)
 {
-    if(mBlock->iWorldX + mBlock->iSizeX < iCameraPosX)
+    if(mBlock->iWorldX + mBlock->iSizeX < INT4(iCameraPosX))
         return 1;
     else
         return 0;
@@ -554,8 +563,8 @@ static int chopBlockOffscreen(struct CBlock *mBlock)

 static int chopParticleOffscreen(struct CParticle *mParticle)
 {
-    if (mParticle->iWorldX < iCameraPosX || mParticle->iWorldY < 0 ||
-        mParticle->iWorldY > iScreenY || mParticle->iWorldX > iCameraPosX +
+    if (mParticle->iWorldX < INT4(iCameraPosX) || mParticle->iWorldY < 0 ||
+        mParticle->iWorldY > iScreenY || mParticle->iWorldX > INT4(iCameraPosX) +
         iScreenX)
     {
         return 1;
@@ -662,7 +671,7 @@ static void chopDrawTheWorld(void)
 static void chopDrawParticle(struct CParticle *mParticle)
 {

-    int iPosX = (mParticle->iWorldX - iCameraPosX);
+    int iPosX = (mParticle->iWorldX - INT4(iCameraPosX));
     int iPosY = (mParticle->iWorldY);
 #if LCD_DEPTH > 2
     rb->lcd_set_foreground(LCD_RGBPACK(192,192,192));
@@ -683,9 +692,9 @@ static void chopDrawScene(void)
     rb->lcd_set_background(LCD_WHITE);
 #endif
     chopDrawTheWorld();
-    chopDrawPlayer(INT4(iPlayerPosX) - iCameraPosX, INT4(iPlayerPosY));
+    chopDrawPlayer(INT4(iPlayerPosX - iCameraPosX, iPlayerPosY));

-    score = -20 + INT4(FIXED4_DIV(iPlayerPosX, FIXED4(3)));
+    score = -20 + INT4(iPlayerPosX / 3);

 #if LCD_DEPTH == 1
     rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
@@ -837,7 +846,7 @@ static int chopGameLoop(void)

         if(iGravityTimerCountdown <= 0)
         {
-            iGravityTimerCountdown = 3;
+            iGravityTimerCountdown = 3*CHOPPER_SPEED_FACTOR;
             chopAddParticle(INT4(iPlayerPosX), INT4(iPlayerPosY)+5, 0, 0);
         }

@@ -867,7 +876,7 @@ static int chopGameLoop(void)
                    )
                     bdelay = -2;
                 if (bdelay == 0)
-                    iPlayerSpeedY = FIXED4(-3);
+                    iPlayerSpeedY = FIXED4(-3) / CHOPPER_SPEED_FACTOR;
                 break;

             default:
@@ -878,7 +887,7 @@ static int chopGameLoop(void)
                    )
                     bdelay = 3;
                 if (bdelay == 0)
-                    iPlayerSpeedY = FIXED4(4);
+                    iPlayerSpeedY = FIXED4(4) / CHOPPER_SPEED_FACTOR;

                 if (rb->default_event_handler(move_button) == SYS_USB_CONNECTED)
                     return PLUGIN_USB_CONNECTED;
@@ -887,20 +896,20 @@ static int chopGameLoop(void)
         last_button = move_button;

         if (bdelay < 0) {
-            iPlayerSpeedY = FIXED4(bdelay);
+            iPlayerSpeedY = FIXED4(bdelay) / CHOPPER_SPEED_FACTOR;
             bdelay++;
         } else if (bdelay > 0) {
-            iPlayerSpeedY = FIXED4(bdelay);
+            iPlayerSpeedY = FIXED4(bdelay) / CHOPPER_SPEED_FACTOR;
             bdelay--;
         }

-        iCameraPosX = INT4(iPlayerPosX) - 25;
+        iCameraPosX = iPlayerPosX - FIXED4(25);
         iPlayerPosX += iPlayerSpeedX;
         iPlayerPosY += iPlayerSpeedY;

         chopCounter++;
         /* increase speed as we go along */
-        if (chopCounter == 100){
+        if (chopCounter == 100*CHOPPER_SPEED_FACTOR*CHOPPER_SPEED_FACTOR){
             iPlayerSpeedX += FIXED4(1);
             chopCounter=0;
         }
@@ -937,7 +946,7 @@ static int chopGameLoop(void)

 static void chopDrawBlock(struct CBlock *mBlock)
 {
-    int iPosX = (mBlock->iWorldX - iCameraPosX);
+    int iPosX = (mBlock->iWorldX - INT4(iCameraPosX));
     int iPosY = (mBlock->iWorldY);
 #if LCD_DEPTH > 2
     rb->lcd_set_foreground(LCD_RGBPACK(100,255,100));
@@ -965,10 +974,10 @@ static void chopRenderTerrain(struct CTerrain *ter)
     while(i < ter->iNodesCount && oldx < iScreenX)
     {

-        int x = ter->mNodes[i-1].x - iCameraPosX;
+        int x = ter->mNodes[i-1].x - INT4(iCameraPosX);
         int y = ter->mNodes[i-1].y;

-        int x2 = ter->mNodes[i].x - iCameraPosX;
+        int x2 = ter->mNodes[i].x - INT4(iCameraPosX);
         int y2 = ter->mNodes[i].y;
 #if LCD_DEPTH > 2
         rb->lcd_set_foreground(LCD_RGBPACK(100,255,100));
@@ -1014,13 +1023,13 @@ void chopper_load(bool newgame)
     }
     iRotorOffset = 0;
     iPlayerPosX = FIXED4(60);
-    iPlayerPosY = FIXED4_DIV(FIXED4(iScreenY << 2),FIXED4(10));
+    iPlayerPosY = FIXED4(iScreenY*4) / 10;
     iLastBlockPlacedPosX = 0;
-    iGravityTimerCountdown = 2;
+    iGravityTimerCountdown = 2*CHOPPER_SPEED_FACTOR;
     chopCounter = 0;
-    iPlayerSpeedX = FIXED4(3);
+    iPlayerSpeedX = FIXED4(3) / CHOPPER_SPEED_FACTOR;
     iPlayerSpeedY = 0;
-    iCameraPosX = 30;
+    iCameraPosX = FIXED4(30);

     for (i=0; i < NUMBER_OF_PARTICLES; i++)
         mParticles[i].bIsActive = 0;
@@ -1039,8 +1048,9 @@ void chopper_load(bool newgame)
         chopCopyTerrain(&mGround, &mRoof, 0, - ( (iScreenY * 3) / 4));

     if (iLevelMode == LEVEL_MODE_NORMAL)
-        /* make it a bit more exciting, cause it's easy terrain... */
-        iPlayerSpeedX <<= 1 ;
+        /* make it a bit more exciting, cause it's easy terrain...
+         * double the speed (safe for fp)*/
+        iPlayerSpeedX += iPlayerSpeedX;
 }

 /* this is the plugin entry point */