#include "../include/circuit.h" #include "../include/segment.h" #include "../include/camera.h" #include "../include/clouds.h" #include "../include/cars.h" #include "../parameters.h" #include #include #include #include "../include/drawstuff.h" #include "../colors.h" extern std::vector circuit; extern std::vector nuages; extern std::vector traffic; extern camera *cam; extern uint16_t currentcurve; extern uint8_t shiftcolor; extern int MAX_SEGMENT; extern bool ShowDebug1; extern bopti_image_t car1, car2, car3, car4, car5, car6, car7, car8; extern bopti_image_t pl_tree1, pl_tree2, pl_tree3, pl_tree4, dt_tree1, dt_tree2, dt_tree3, dt_tree4, us_tree4, fi_tree1, fi_tree2, fi_tree4; extern bopti_image_t cc_bigleaf, cc_smallleaf, cc_rocks, af_bigleaf, dt_smallleaf, fi_rocks; extern bopti_image_t sky1, sky2, sky3; extern bopti_image_t mountain; extern bopti_image_t treeline; extern bopti_image_t leftturn, rightturn, uphill, downhill; extern bopti_image_t checkpoint, startlights, stoplights, waitlights; bopti_image_t *scaledTrees[NB_TREES_TYPES][MAX_SUBIMAGES_TREES] = { 0 }; bopti_image_t *scaledCars[NB_CARS_TYPES][MAX_SUBIMAGES_CARS] = { 0 }; extern int CurrentCircuitBiome; size_t image_size_profile(int profile, int width, int height) { size_t size = sizeof(bopti_image_t); if(profile == 0 || profile == 1) // PX_RGB565, PX_RGB565A size += width * height * 2; else if(profile == 2) // PX_P8 size += 512 + width * height; else if(profile == 3) // PX_P4 size += 32 + ((width + 1) / 2) * height; return size; } size_t image_size(bopti_image_t const *img) { return image_size_profile(img->profile, img->width, img->height); } int get_pixel(bopti_image_t const *img, int x, int y) { if((unsigned)x >= img->width || (unsigned)y >= img->height) return 0; uint8_t *bytes = (void *)img->data; if(img->profile <= 1) return img->data[y * img->width + x]; if(img->profile == 2) return bytes[y * img->width + x + 512]; if(img->profile == 3) { int s = (img->width + 1) >> 1; int i = y * s + (x >> 1) + 32; if(x & 1) return bytes[i] & 0x0f; else return bytes[i] >> 4; } return 0; } void set_pixel(bopti_image_t *img, int x, int y, int color) { if((unsigned)x >= img->width || (unsigned)y >= img->height) return; uint8_t *bytes = (void *)img->data; if(img->profile <= 1) img->data[y * img->width + x] = color; else if(img->profile == 2) bytes[y * img->width + x + 512] = color; else if(img->profile == 3) { int s = (img->width + 1) >> 1; int i = y * s + (x >> 1) + 32; if(x & 1) bytes[i] = (bytes[i] & 0xf0) | (color & 0x0f); else bytes[i] = (bytes[i] & 0x0f) | ((color & 0x0f) << 4); } } bopti_image_t *resize(bopti_image_t const *src, int w, int h) { size_t size = image_size_profile(src->profile, w, h); bopti_image_t *img = malloc(size); if(!img) return NULL; size_t palette_size = 0; if(src->profile == 2) // PX_P8 palette_size = 512; else if(src->profile == 3) // PX_P4 palette_size = 32; img->profile = src->profile; img->alpha = src->alpha; img->width = w; img->height = h; memcpy(img->data, src->data, palette_size); for(int y = 0; y < h; y++) for(int x = 0; x < w; x++) { int color = get_pixel(src, x * src->width / w, y * src->height / h); set_pixel(img, x, y, color); } return img; } void initData( void ) { cam = new camera(); cam->cX = fixdouble(0.0f); cam->cY = fixdouble(300.0f); cam->cZ = fixdouble(0.0f); } void createCircuit( void ) { addStartLine( PLAINS ); addStraightLine( L_VERYSHORT, PLAINS ); addStraightLine( L_VERYSHORT, DESERT ); addStraightLine( L_VERYSHORT, USA ); addStraightLine( L_VERYSHORT, FINLAND ); addStraightLine( L_VERYSHORT, AFRICA ); addCurvyHill( L_MEDIUM, H_BIG, UP_HILL, C_HARD, LEFT_CURVE, USA ); addCurvyHill( L_MEDIUM, H_BIG, UP_HILL, C_HARD, LEFT_CURVE, DESERT ); addStraightLine( L_VERYSHORT, DESERT ); addCurvyHill( L_MEDIUM, H_BIG, DOWN_HILL, C_HARD, RIGHT_CURVE, DESERT ); addCheckPoint( PLAINS ); addStraightLine( L_VERYSHORT, PLAINS ); addCheckPoint( DESERT ); addCurve( L_SHORT, C_HARD, LEFT_CURVE, DESERT ); addCurve( L_SHORT, C_HARD, RIGHT_CURVE, DESERT ); addStraightLine( L_LONG, DESERT ); addHill( L_MEDIUM, H_BIG, UP_HILL, DESERT ); addHill( L_MEDIUM, H_BIG, DOWN_HILL, PLAINS ); addStraightLine( L_VERYLONG, PLAINS ); addCurve( L_SHORT, C_HARD, LEFT_CURVE, PLAINS ); addStraightLine( L_VERYLONG, DESERT ); addCurve( L_SHORT, C_EASY, LEFT_CURVE, DESERT ); addCheckPoint( PLAINS ); addFinishLine( DESERT ); addStraightLine( L_VERYSHORT, PLAINS ); }; void putBillBoards( void ) { for (int k = 0; kCurve; int currentcurve = circuit[k]->Curve; int nextslope = circuit[k+3]->Slope; int currentslope = circuit[k]->Slope; if (nextcurve==currentcurve && nextslope==currentslope) { // no turn and no hill } else if (nextcurve==currentcurve && nextslope!=currentslope) { // no turn but hill if (nextslope>0) //uphill { circuit[k]->RDeco=UPHILL; circuit[k]->LDeco=UPHILL; } else if (nextslope<0) //downhill { circuit[k]->RDeco=DOWNHILL; circuit[k]->LDeco=DOWNHILL; } } else if (nextcurve!=currentcurve && nextslope==currentslope) { // no turn but hill if (nextcurve<0) //uphill { circuit[k]->RDeco=LEFTTURN; circuit[k]->LDeco=LEFTTURN; } else if (nextcurve>0) //downhill { circuit[k]->RDeco=RIGHTTURN; circuit[k]->LDeco=RIGHTTURN; } } else if (nextcurve!=currentcurve && nextslope!=currentslope) { // no turn but hill if (nextcurve<0) //uphill { circuit[k]->RDeco=LEFTTURN; if (nextslope>0) circuit[k]->LDeco=UPHILL; else if (nextslope<0) circuit[k]->LDeco=DOWNHILL; } else if (nextcurve>0) //downhill { circuit[k]->LDeco=RIGHTTURN; if (nextslope>0) circuit[k]->RDeco=UPHILL; else if (nextslope<0) circuit[k]->RDeco=DOWNHILL; } } if (nextcurve<0 && currentcurve!=nextcurve) circuit[k]->RDeco=LEFTTURN; if (nextcurve>0 && currentcurve!=nextcurve) circuit[k]->LDeco=RIGHTTURN; } } void createClouds( void ) { srand( rtc_ticks() ); for( int k = 0; k < NB_CLOUDS_SKY; k++) { int X = (rand() % 792); int Y = rand() % 60; int T = rand() % 3; Clouds* cl=new Clouds( X, Y, T ); if (cl!=nullptr) nuages.push_back( cl ); } } void createTraffic( void ) { srand( rtc_ticks() ); for( int k = 0; k < NB_CARS_TRAFFIC; k++) { int8_t X = rand() % 4; //double Z = (double) (rand() % 4000); //int8_t X = 0; double Z = (k+1)*SEGMENT_LENGTH; uint8_t S = 4 + (rand() % 2); uint8_t T = rand() % 8; Cars* car; // Depending on which line the car is placed, we choose the right fraction of W if (X==0) car = new Cars( -0.75, (double) Z, S, T ); else if (X==1) car = new Cars( -0.25, (double) Z, S, T ); else if (X==2) car = new Cars( 0.25, (double) Z, S, T ); else if (X==3) car = new Cars( 0.75, (double) Z, S, T ); if (car!=nullptr) traffic.push_back( car ); } } void addCheckPoint( int8_t biome ) { double lastZ=0; int16_t lastY=0; uint16_t lastIndex = circuit.size(); if (lastIndex!=0) { lastY=circuit[lastIndex-1]->wY; lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } for( int i=0; i<5; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, -1, -1 ); if (seg!=nullptr) { seg->Environment = biome; circuit.push_back( seg ); } } for( int i=5; i<10; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, CHECK, CHECK ); if (seg!=nullptr) { seg->Environment = biome; if (i==7) seg->Special = CHECKPOINT; circuit.push_back( seg ); } } for( int i=10; i<15; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, -1, -1 ); if (seg!=nullptr) { seg->Environment = biome; circuit.push_back( seg ); } } } void addStartLine( int8_t biome ) { double lastZ=0; int16_t lastY=0; uint16_t lastIndex = circuit.size(); if (lastIndex!=0) { lastY=circuit[lastIndex-1]->wY; lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } for( int i=0; i<5; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, -1, -1 ); if (seg!=nullptr) { seg->Environment = biome; circuit.push_back( seg ); } } for( int i=5; i<10; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, STARTLIGHT, STARTLIGHT ); if (seg!=nullptr) { seg->Environment = biome; if (i==7) seg->Special = START; circuit.push_back( seg ); } } for( int i=10; i<15; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, -1, -1 ); if (seg!=nullptr) { seg->Environment = biome; circuit.push_back( seg ); } } } void addFinishLine( int8_t biome ) { double lastZ=0; int16_t lastY=0; uint16_t lastIndex = circuit.size(); if (lastIndex!=0) { lastY=circuit[lastIndex-1]->wY; lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } for( int i=0; i<5; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, -1, -1 ); if (seg!=nullptr) { seg->Environment = biome; circuit.push_back( seg ); } } for( int i=5; i<10; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, STOPLIGHT, STOPLIGHT ); if (seg!=nullptr) { seg->Environment = biome; if (i==7) seg->Special = FINISH; circuit.push_back( seg ); } } for( int i=10; i<15; i++) { Segment *seg=new Segment( 0, lastY, lastZ + i*SEGMENT_LENGTH, 0, 0, -1, -1 ); if (seg!=nullptr) { seg->Environment = biome; circuit.push_back( seg ); } } } void addStraightLine( Length l, int8_t biome ) { double lastZ=0; int16_t lastY=0; uint16_t lastIndex = circuit.size(); if (lastIndex!=0) { lastY=circuit[lastIndex-1]->wY; lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } srand( rtc_ticks() ); for( int i=0; iEnvironment = biome; circuit.push_back( seg ); } } } void addCurve( Length l, CurveStrength s, CurveType t, int8_t biome ) { double lastZ=0; int16_t lastY=0; uint16_t lastIndex = circuit.size(); if (lastIndex!=0) { lastY=circuit[lastIndex-1]->wY; lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } srand( rtc_ticks() ); for( int i=0; iEnvironment = biome; circuit.push_back( seg ); } } } void addHill( Length l, HillSize s, HillType t, int8_t biome ) { double lastZ=0; int16_t lastY=0; uint16_t lastIndex = circuit.size(); if (lastIndex!=0) { lastY=circuit[lastIndex-1]->wY; lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } srand( rtc_ticks() ); for( int i=0; iEnvironment = biome; circuit.push_back( seg ); } } } void addCurvyHill( Length l, HillSize s, HillType t, CurveStrength cs, CurveType ct, int8_t biome ) { double lastZ=0; int16_t lastY=0; uint16_t lastIndex = circuit.size(); if (lastIndex!=0) { lastY=circuit[lastIndex-1]->wY; lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } srand( rtc_ticks() ); for( int i=0; iEnvironment = biome; circuit.push_back( seg ); } } } void projectCircuitFP( void ) { for( int i=0; iProject3DFP( cam ); } }; void projectCircuitFP( uint16_t index ) { circuit[index]->Project3DFP( cam ); }; void printCircuit( void ) { for( int i=0; i<20; i++) { dprint(198, 1+10*(i), C_RED, "%d-(sX,Y,W)=(%d,%d,%d)", i, circuit[i]->X, circuit[i]->Y, circuit[i]->W ); //dprint(1, 1+10*(i), C_GREEN, "%d-(_sY,Y,W)=(%.0f,%.0f,%.0f)", i, circuit[i]->_wX, circuit[i]->_wY, circuit[i]->_sW ); } }; void printCircuit( int i ) { dprint(1, 1+10*(i), C_RED, "%d-(wX,Y,Z)=(%d,%d,%d)", i, fround(circuit[i]->wX), fround(circuit[i]->wY), fround(circuit[i]->wZ) ); dprint(198, 1+10*(i), C_RED, "%d-(sX,Y,W)=(%d,%d,%d)", i, circuit[i]->X, circuit[i]->Y, circuit[i]->W ); }; void drawCircuitSegment( uint16_t index ) { if (index>=circuit.size()-1) return; int X1 = (int) circuit[index]->X; int Y1 = (int) circuit[index]->Y; int W1 = (int) circuit[index]->W; int X2 = (int) circuit[(index+1)]->X + circuit[index]->Curve; int Y2 = (int) circuit[(index+1)]->Y; int W2 = (int) circuit[(index+1)]->W; if (Y1==Y2) return; if (circuit[index]->Environment == PLAINS) { if (index%2==0) { drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, DARK_GREEN_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, LIGHT_GREY_ROAD ); drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, DARK_GREEN_GRASS ); } else { drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, LIGHT_GREEN_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, RED_STRIPE ); drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, RED_STRIPE ); drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, LIGHT_GREEN_GRASS ); } } else if (circuit[index]->Environment == DESERT) { if (index%2==0) { drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, DARK_YELLOW_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, LIGHT_GREY_ROAD ); drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, DARK_YELLOW_GRASS ); } else { drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, LIGHT_YELLOW_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, RED_STRIPE ); drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, RED_STRIPE ); drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, LIGHT_YELLOW_GRASS ); } } else if (circuit[index]->Environment == USA) { if (index%2==0) { drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, DARK_GREEN_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, BLACK_ROAD ); drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/25+currentcurve, X2-W2/50+currentcurve, Y2, X1-W1/25+currentcurve, X1-W1/50+currentcurve, Y1, YELLOW_STRIPE ); drawPolygon( X2+W2/50+currentcurve, X2+W2/25+currentcurve, Y2, X1+W1/50+currentcurve, X1+W1/25+currentcurve, Y1, YELLOW_STRIPE ); drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, DARK_GREEN_GRASS ); } else { drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, LIGHT_GREEN_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, BLACK_ROAD ); drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2-W2/25+currentcurve, X2-W2/50+currentcurve, Y2, X1-W1/25+currentcurve, X1-W1/50+currentcurve, Y1, YELLOW_STRIPE ); drawPolygon( X2+W2/50+currentcurve, X2+W2/25+currentcurve, Y2, X1+W1/50+currentcurve, X1+W1/25+currentcurve, Y1, YELLOW_STRIPE ); drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, WHITE_STRIPE ); drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, LIGHT_GREEN_GRASS ); } } else if (circuit[index]->Environment == FINLAND) { if (index%2==0) { drawPolygon( 0, X2-W2+currentcurve, Y2, 0, X1-W1+currentcurve, Y1, DARK_SNOW_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, SNOW_ROAD ); drawPolygon( X2-W2/2-W2/12+currentcurve, X2-W2/2-W2/12-W2/25+currentcurve, Y2, X1-W1/2-W1/12+currentcurve, X1-W1/2-W1/12-W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2+W2/12+W2/25+currentcurve, X2-W2+W2/12+currentcurve, Y2, X1-W1+W1/12+W1/25+currentcurve, X1-W1+W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2/12+currentcurve, X2-W2/12-W2/25+currentcurve, Y2, X1-W1/12+currentcurve, X1-W1/12-W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2/2+W2/12+W2/25+currentcurve, X2-W2/2+W2/12+currentcurve, Y2, X1-W1/2+W1/12+W1/25+currentcurve, X1-W1/2+W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2/12+currentcurve, X2+W2/12+W2/25+currentcurve, Y2, X1+W1/12+currentcurve, X1+W1/12+W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2/2-W2/12-W2/25+currentcurve, X2+W2/2-W2/12+currentcurve, Y2, X1+W1/2-W1/12-W1/25+currentcurve, X1+W1/2-W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2/2+W2/12+currentcurve, X2+W2/2+W2/12+W2/25+currentcurve, Y2, X1+W1/2+W1/12+currentcurve, X1+W1/2+W1/12+W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2-W2/12-W2/25+currentcurve, X2+W2-W2/12+currentcurve, Y2, X1+W1-W1/12-W1/25+currentcurve, X1+W1-W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2+currentcurve, 396, Y2, X1+W1+currentcurve, 396, Y1, DARK_SNOW_GRASS ); } else { drawPolygon( 0, X2-W2+currentcurve, Y2, 0, X1-W1+currentcurve, Y1, LIGHT_SNOW_GRASS ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, SNOW_ROAD ); drawPolygon( X2-W2/2-W2/12+currentcurve, X2-W2/2-W2/12-W2/25+currentcurve, Y2, X1-W1/2-W1/12+currentcurve, X1-W1/2-W1/12-W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2+W2/12+W2/25+currentcurve, X2-W2+W2/12+currentcurve, Y2, X1-W1+W1/12+W1/25+currentcurve, X1-W1+W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2/12+currentcurve, X2-W2/12-W2/25+currentcurve, Y2, X1-W1/12+currentcurve, X1-W1/12-W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2-W2/2+W2/12+W2/25+currentcurve, X2-W2/2+W2/12+currentcurve, Y2, X1-W1/2+W1/12+W1/25+currentcurve, X1-W1/2+W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2/12+currentcurve, X2+W2/12+W2/25+currentcurve, Y2, X1+W1/12+currentcurve, X1+W1/12+W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2/2-W2/12-W2/25+currentcurve, X2+W2/2-W2/12+currentcurve, Y2, X1+W1/2-W1/12-W1/25+currentcurve, X1+W1/2-W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2/2+W2/12+currentcurve, X2+W2/2+W2/12+W2/25+currentcurve, Y2, X1+W1/2+W1/12+currentcurve, X1+W1/2+W1/12+W1/25+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2-W2/12-W2/25+currentcurve, X2+W2-W2/12+currentcurve, Y2, X1+W1-W1/12-W1/25+currentcurve, X1+W1-W1/12+currentcurve, Y1, DARK_GREY_ROAD ); drawPolygon( X2+W2+currentcurve, 396, Y2, X1+W1+currentcurve, 396, Y1, LIGHT_SNOW_GRASS ); } } else if (circuit[index]->Environment == AFRICA) { if (index%2==0) { drawPolygon( 0, X2-W2+currentcurve, Y2, 0, X1-W1+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, OCRE_ROAD ); drawPolygon( X2-W2/2-W2/12+currentcurve, X2-W2/2-W2/12-W2/25+currentcurve, Y2, X1-W1/2-W1/12+currentcurve, X1-W1/2-W1/12-W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2+W2/12+W2/25+currentcurve, X2-W2+W2/12+currentcurve, Y2, X1-W1+W1/12+W1/25+currentcurve, X1-W1+W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2/12+currentcurve, X2-W2/12-W2/25+currentcurve, Y2, X1-W1/12+currentcurve, X1-W1/12-W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2/2+W2/12+W2/25+currentcurve, X2-W2/2+W2/12+currentcurve, Y2, X1-W1/2+W1/12+W1/25+currentcurve, X1-W1/2+W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2/12+currentcurve, X2+W2/12+W2/25+currentcurve, Y2, X1+W1/12+currentcurve, X1+W1/12+W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2/2-W2/12-W2/25+currentcurve, X2+W2/2-W2/12+currentcurve, Y2, X1+W1/2-W1/12-W1/25+currentcurve, X1+W1/2-W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2/2+W2/12+currentcurve, X2+W2/2+W2/12+W2/25+currentcurve, Y2, X1+W1/2+W1/12+currentcurve, X1+W1/2+W1/12+W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2-W2/12-W2/25+currentcurve, X2+W2-W2/12+currentcurve, Y2, X1+W1-W1/12-W1/25+currentcurve, X1+W1-W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, LIGHT_GREEN_GRASS ); drawPolygon( X2+W2+currentcurve, 396, Y2, X1+W1+currentcurve, 396, Y1, DARK_EARTH ); } else { drawPolygon( 0, X2-W2+currentcurve, Y2, 0, X1-W1+currentcurve, Y1, LIGHT_EARTH ); drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, OCRE_ROAD ); drawPolygon( X2-W2/2-W2/12+currentcurve, X2-W2/2-W2/12-W2/25+currentcurve, Y2, X1-W1/2-W1/12+currentcurve, X1-W1/2-W1/12-W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2+W2/12+W2/25+currentcurve, X2-W2+W2/12+currentcurve, Y2, X1-W1+W1/12+W1/25+currentcurve, X1-W1+W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2/12+currentcurve, X2-W2/12-W2/25+currentcurve, Y2, X1-W1/12+currentcurve, X1-W1/12-W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2/2+W2/12+W2/25+currentcurve, X2-W2/2+W2/12+currentcurve, Y2, X1-W1/2+W1/12+W1/25+currentcurve, X1-W1/2+W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2/12+currentcurve, X2+W2/12+W2/25+currentcurve, Y2, X1+W1/12+currentcurve, X1+W1/12+W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2/2-W2/12-W2/25+currentcurve, X2+W2/2-W2/12+currentcurve, Y2, X1+W1/2-W1/12-W1/25+currentcurve, X1+W1/2-W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2/2+W2/12+currentcurve, X2+W2/2+W2/12+W2/25+currentcurve, Y2, X1+W1/2+W1/12+currentcurve, X1+W1/2+W1/12+W1/25+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2+W2-W2/12-W2/25+currentcurve, X2+W2-W2/12+currentcurve, Y2, X1+W1-W1/12-W1/25+currentcurve, X1+W1-W1/12+currentcurve, Y1, DARK_EARTH ); drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, LIGHT_GREEN_GRASS ); drawPolygon( X2+W2+currentcurve, 396, Y2, X1+W1+currentcurve, 396, Y1, LIGHT_EARTH ); } } } fixed_t interpolatePositionX( double currentZ ) { int index = (int) (currentZ / SEGMENT_LENGTH); fixed_t x1 = fix(circuit[index]->wX); fixed_t x2 = fix(circuit[index+1]->wX); fixed_t dZ = fixdouble(currentZ-index*SEGMENT_LENGTH); fixed_t result = x1 + fmul( x2-x1, fdiv( dZ, fix(SEGMENT_LENGTH))); if(ShowDebug1) { dprint( 120, 1, C_WHITE, "CZ=%.0lf", f2double(currentZ) ); dprint( 120, 15, C_WHITE, "y1=%d", fround(x1) ); dprint( 120, 29, C_WHITE, "y2=%d", fround(x2) ); dprint( 240, 15, C_WHITE, "Dz=%d", fround(dZ) ); dprint( 240, 29, C_GREEN, "CX=%d", fround(result) ); } return result; } fixed_t interpolatePositionY( double currentZ ) { int index = (int) (currentZ / SEGMENT_LENGTH); fixed_t y1 = fix(circuit[index]->wY); fixed_t y2 = fix(circuit[index+1]->wY); fixed_t dZ = fixdouble(currentZ-index*SEGMENT_LENGTH); fixed_t result = y1 + fmul( y2-y1, fdiv( dZ, fix(SEGMENT_LENGTH))); if(ShowDebug1) { dprint( 120, 1, C_WHITE, "CZ=%.0lf", f2double(currentZ) ); dprint( 120, 15, C_WHITE, "y1=%d", fround(y1) ); dprint( 120, 29, C_WHITE, "y2=%d", fround(y2) ); dprint( 240, 15, C_WHITE, "Dz=%d", fround(dZ) ); dprint( 240, 43, C_GREEN, "CY=%d", fround(result) ); } return result; } uint16_t findIndex( double currentZ ) { return (uint16_t) (currentZ / SEGMENT_LENGTH); } void prepareDecoration( int biometoload ) { bopti_image_t const *src; for( int k=0; kwidth * scale); int height = (int) ((float) src->height * scale); scaledTrees[k][i] = resize(src, width, height); //scale*=0.82; } } } void prepareTraffic( void ) { bopti_image_t const *src; for( int k=0; kwidth * scale); int height = (int) ((float) src->height * scale); scaledCars[k][i] = resize(src, width, height); scale*=0.82; } } } void freeDecoration( void ) { for( int k=0; kwZ) - cam->cZ), fix(SEGMENT_LENGTH) )) - 1; if (distance<0) distance = 0; else if (distance>(MAX_SUBIMAGES_TREES-1)) distance = (MAX_SUBIMAGES_TREES-1); //circuit[index]->DScale = distance; int deco = circuit[index]->LDeco; if (deco!=-1) { image = scaledTrees[deco][distance]; int X = circuit[index]->X + circuit[index]->CumulatedCurve - 1.5*circuit[index]->W - image->width/2; int Y = circuit[index]->Y - image->height; dimage( X, Y, image ); } deco = circuit[index]->RDeco; if (deco!=-1) { image = scaledTrees[deco][distance]; int X = circuit[index]->X + circuit[index]->CumulatedCurve + 1.5*circuit[index]->W - image->width/2; int Y = circuit[index]->Y - image->height; dimage( X, Y, image ); } } void updateTraffic( float dt, uint32_t maxdistance ) { for(int k=0; kwZ += traffic[k]->Speed*dt; if (traffic[k]->wZ>maxdistance) traffic[k]->wZ-=maxdistance; } } void drawTraffic( uint16_t index ) { bopti_image_t *image; int distance = fround(fdiv( (fixdouble(traffic[index]->wZ) - cam->cZ), fix(SEGMENT_LENGTH/2) ))-2; if (distance<0) distance = 0; else if (distance>(MAX_SUBIMAGES_CARS-1)) distance = (MAX_SUBIMAGES_CARS-1); //int segnumber = findIndex( traffic[index]->wZ ); //traffic[index]->segnum = segnumber; //traffic[index]->DScale = distance; image = scaledCars[traffic[index]->Type][distance]; int X = traffic[index]->X - image->width/2; int Y = traffic[index]->Y - image->height; dimage( X, Y, image ); } void drawClouds( int offset ) { bopti_image_t *cloud; for( int k =0; kType==0) cloud=&sky1; else if (nuages[k]->Type==1) cloud=&sky2; else cloud=&sky3; nuages[k]->X--; if (nuages[k]->X>792) nuages[k]->X-=396*3; else if (nuages[k]->X<-396) nuages[k]->X+=396*3; dimage( nuages[k]->X, nuages[k]->Y, cloud ); } } void drawFarBackground( int offset ) { int X = offset; int DX = mountain.width; while (X>0) { X-=DX; } do { if (X>-1*DX) dimage(X, 60, &mountain); X+=DX; } while(X0) { X-=DX; } do { if (X>-1*DX) dimage(X, 90, &treeline); X+=DX; } while(X