I am trying to convert floating point to fixed point because the hardware does not have floating point acceleration. I cannot seem to find my mistake for the variable screen_X the value is always 320.0. The precision is Q38,26 (edit useful bits are Q6.26, 64 bit variables are used for mul and div compatibility).
#define fixed_precision 26 #define CONV_F(A) (A*conv_fixed_precision) #define CONV_DF(A) (A/(1<<fixed_precision)) #define MUL38_26(A, B)((long long)(A*B)>>fixed_precision) #define DIV38_26(A, B)((long long)(A<<fixed_precision)/B) // global variable double conv_fixed_precision = (1 << fixed_precision); The floating point code is the following :
void draw_balls(VGA& vga) { int i; for (i = 0; i < NB_BALL; i++) { if (R_Ball[i] == 0) continue; // the pearl has already been found double screen_X = X_Ball[i]; double screen_Y = Y_Ball[i]; screen_X -= X_position; screen_Y -= Y_position; screen_X *= Scale; screen_Y *= Scale; double screen_Radius = R_Ball[i] * Scale; if ((screen_X * screen_X + screen_Y * screen_Y <= screen_Radius * screen_Radius)) { //La perle est trouvee R_Ball[i] = 0; int time = get_time(); printf("Found %i pearl(s) at time %i\n", ++found_pearl, time); } double tmp_X = screen_X; double tmp_Y = screen_Y; screen_X = (tmp_X * cosAngle - tmp_Y * sinAngle) * 240 + 320; screen_Y = (tmp_X * sinAngle + tmp_Y * cosAngle) * 240 + 240; screen_Radius *= 240; if (screen_X + screen_Radius < 0) break; if (screen_X - screen_Radius >= 640) break; if (screen_Y + screen_Radius < 0) break; if (screen_Y - screen_Radius >= 480) break; drawBall3D(vga, screen_X, screen_Y, screen_Radius, i % 7); } #ifdef USE_OPEN_GL glFlush(); #endif and the fixed point code is the following:
void draw_balls(VGA & vga) { int i; long long cosAngF = CONV_F(cosAngle); long long sinAngF = CONV_F(sinAngle); long long scaleF = CONV_F(Scale); long long xPosF = CONV_F(X_position); long long yPosF = CONV_F(Y_position); for (i = 0; i < NB_BALL; i++) { if (R_Ball[i] == 0) continue; // the pearl has already been found long long screen_X = CONV_F(X_Ball[i]); long long screen_Y = CONV_F(Y_Ball[i]); screen_X -= xPosF; screen_Y -= yPosF; screen_X = MUL38_26(screen_X, scaleF); screen_Y = MUL38_26(screen_Y, scaleF); long long screen_Radius = CONV_F(R_Ball[i] * Scale); if ((MUL38_26(screen_X, screen_X) + MUL38_26(screen_Y, screen_Y)) <= MUL38_26(screen_Radius, screen_Radius)) { //La perle est trouvee R_Ball[i] = 0; int time = get_time(); printf("Found %i pearl(s) at time %i\n", ++found_pearl, time); } long long tmp_X = screen_X; long long tmp_Y = screen_Y; long long F240 = ((long long)240)<<fixed_precision; long long F320 = ((long long)320) << fixed_precision; screen_X = MUL38_26(MUL38_26(tmp_X, cosAngF) - MUL38_26(tmp_Y, sinAngF), F240) + F320; screen_Y = MUL38_26(MUL38_26(tmp_X, sinAngF) + MUL38_26(tmp_Y, cosAngF), F240) + F240; screen_Radius = MUL38_26(screen_Radius, F240); long long F640 = ((long long)640) << fixed_precision; long long F480 = ((long long)480) << fixed_precision; if (screen_X + screen_Radius < 0) break; if (screen_X - screen_Radius >= F640) break; if (screen_Y + screen_Radius < 0) break; if (screen_Y - screen_Radius >= F480) break; drawBall3D(vga, screen_X>>fixed_precision, screen_Y >> fixed_precision, screen_Radius >> fixed_precision, i % 7); } #ifdef USE_OPEN_GL glFlush(); #endif #endif }
int64_tmake it clear what you're using versuslong long?#defines? It doesn't help anyone if you post wrong code.conv_fixed_precisiondefined?