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 */