diff --git a/CMakeLists.txt b/CMakeLists.txt index 840f4d8..38e27a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ set(SOURCES src/src/circuit.cc src/src/drawstuff.cc src/src/clouds.cc + src/src/cars.cc # ... ) diff --git a/CppOutRun.cbp b/CppOutRun.cbp index 70e132b..6a04d9f 100644 --- a/CppOutRun.cbp +++ b/CppOutRun.cbp @@ -28,8 +28,10 @@ + + @@ -37,6 +39,7 @@ + diff --git a/CppOutRun.layout b/CppOutRun.layout index ad57dc2..08458e5 100644 --- a/CppOutRun.layout +++ b/CppOutRun.layout @@ -2,64 +2,98 @@ - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/colors.h b/src/colors.h new file mode 100644 index 0000000..9eb8c39 --- /dev/null +++ b/src/colors.h @@ -0,0 +1,19 @@ +#ifndef COLORS_H +#define COLORS_H + + +#define LIGHT_GREY_ROAD 0xC638 +#define DARK_GREY_ROAD 0xBDD7 //0xB5B6 + +#define WHITE_STRIPE 0xFFFF +#define RED_STRIPE 0xF800 + +#define LIGHT_GREEN_GRASS 0x07E5 +#define DARK_GREEN_GRASS 0x0680 + +#define LIGHT_YELLOW_GRASS 0xFFE0 +#define DARK_YELLOW_GRASS 0xD6A0 + +#define DAY_BLUE_SKY 0x017F + +#endif // PARAMETERS_H diff --git a/src/include/cars.h b/src/include/cars.h new file mode 100644 index 0000000..3692e00 --- /dev/null +++ b/src/include/cars.h @@ -0,0 +1,34 @@ +#ifndef CARS_H +#define CARS_H + +#include +#include "camera.h" + + +class Cars +{ + public: + Cars(); + Cars( float x, double z, uint8_t s, uint8_t t ); + ~Cars(); + + void Project3DFP( camera* c ); + + + float wX; + double wZ; + + int16_t X; + int16_t Y; + + uint8_t Speed; + uint8_t Type; + + uint8_t DScale; + + // for debugging only + bool visible; + uint16_t segnum; +}; + +#endif // CARS_H diff --git a/src/include/circuit.h b/src/include/circuit.h index 752ac86..112777b 100644 --- a/src/include/circuit.h +++ b/src/include/circuit.h @@ -12,9 +12,11 @@ enum Length enum HillSize { - H_SMALL = 10, - H_MEDIUM = 20, - H_BIG = 40 + H_VERYSMALL = 20, + H_SMALL = 40, + H_MEDIUM = 60, + H_BIG = 80, + H_VERYBIG = 100 }; enum HillType @@ -25,9 +27,11 @@ enum HillType enum CurveStrength { - C_EASY = 2, - C_MEDIUM = 4, - C_HARD = 6 + C_VERYEASY = 2, + C_EASY = 4, + C_MEDIUM = 6, + C_HARD = 8, + C_VERYHARD = 10 }; enum CurveType @@ -46,24 +50,31 @@ enum Decoration void initData( void ); void createCircuit( void ); void createClouds( void ); +void createTraffic( void ); void projectCircuitFP( void ); void projectCircuitFP( uint16_t index ); +void updateTraffic( void ); + void printCircuit( void ); void printCircuit( int i ); void drawCircuitSegment( uint16_t index ); void drawDecoration( uint16_t index ); +void drawTraffic( uint16_t index ); void drawClouds( int offset ); void freeDecoration( void ); void prepareDecoration( void ); -void addStraightLine( Length l ); -void addCurve( Length l, CurveStrength s, CurveType t ); -void addHill( Length l, HillSize s, HillType t ); +void freeTraffic( void ); +void prepareTraffic( void ); + +void addStraightLine( Length l, int8_t biome ); +void addCurve( Length l, CurveStrength s, CurveType t, int8_t biome ); +void addHill( Length l, HillSize s, HillType t, int8_t biome ); fixed_t interpolatePositionX( double currentZ ); fixed_t interpolatePositionY( double currentZ ); - +uint16_t findIndex( double currentZ ); diff --git a/src/include/clouds.h b/src/include/clouds.h index 1f8158a..3ea27d4 100644 --- a/src/include/clouds.h +++ b/src/include/clouds.h @@ -21,7 +21,7 @@ class Clouds int16_t X; int16_t Y; - int8_t type; + int8_t Type; }; #endif // CLOUDS_H diff --git a/src/include/drawstuff.h b/src/include/drawstuff.h index dff6916..43f1385 100644 --- a/src/include/drawstuff.h +++ b/src/include/drawstuff.h @@ -3,8 +3,13 @@ void gint_dhline(int x1, int x2, int y, uint16_t color); void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B ); +void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint16_t color ); void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B ); +void drawGrass( int y1, int y2, uint16_t color ); void drawSky( void ); +void drawSky( uint16_t color ); +void drawSky( uint8_t R, uint8_t G, uint8_t B ); void drawSky( int ymin, int ymax ); +void drawSkyOptimised( uint16_t color ); diff --git a/src/include/segment.h b/src/include/segment.h index c64779a..4a92042 100644 --- a/src/include/segment.h +++ b/src/include/segment.h @@ -5,6 +5,14 @@ #include #include "camera.h" + +enum BiomeType +{ + PLAINS = 0, + DESERT = 1 +}; + + class Segment { public: @@ -16,6 +24,7 @@ class Segment void Project3DFP( camera* c ); + int8_t environment = PLAINS; int8_t Curve=0; int16_t CumulatedCurve=0; diff --git a/src/main.cc b/src/main.cc index 09e3fa7..efba9b0 100644 --- a/src/main.cc +++ b/src/main.cc @@ -13,13 +13,15 @@ #include #include +#include "parameters.h" +#include "colors.h" #include "include/camera.h" #include "include/segment.h" -#include "parameters.h" #include "include/circuit.h" #include "include/drawstuff.h" #include "include/clouds.h" +#include "include/cars.h" extern bopti_image_t car1, car2, car3, car4, car5, car6, car7, car8; @@ -33,6 +35,7 @@ int MAX_SEGMENT=0; camera *cam; std::vector nuages; +std::vector traffic; bool stop = false; @@ -41,16 +44,26 @@ bool screenshot = false; bool ShowDebug1 = false; bool ShowDebug2 = false; +bool BDrawDeco = true; +bool BDrawClds = true; +bool BDrawCars = true; + + uint16_t currentcurve=0; uint8_t shiftcolor=0; float speed = 0; -float maxspeedforward = 8; -float maxspeedbackward = 4; +float maxspeedforward = 5; +float maxspeedbackward = 2; int direction = 1; bool speedcontrol = false; +uint8_t minYRoad = 224; // We will track the upper Y (in fact the minimum Y during the RoadDrawing to optimize the rendering of the Sky + + + + static void get_inputs( float dt ) { key_event_t ev; @@ -108,19 +121,27 @@ static void get_inputs( float dt ) if(keydown(KEY_EXIT)) stop = true; - if(keydown(KEY_F1)) +#if IS_FXLIB==1 + if(keydown(KEY_OPTN)) { ShowDebug1 = !ShowDebug1; ShowDebug2 = false; } - if(keydown(KEY_F2)) + if(keydown(KEY_VARS)) { ShowDebug2 = !ShowDebug2; ShowDebug1 = false; } + if(keydown(KEY_F1)) BDrawDeco = !BDrawDeco; + if(keydown(KEY_F2)) BDrawClds = !BDrawClds; + if(keydown(KEY_F3)) BDrawCars = !BDrawCars; + //if(keydown(KEY_F4)) { } + + if(keydown(KEY_F5)) screenshot = true; if(keydown(KEY_F6)) record = !record; - if(keydown(KEY_F4)) screenshot = true; + +#endif // IS_FXLIB if (speedcontrol==false) { @@ -140,27 +161,27 @@ int main(void) __printf_enable_fp(); __printf_enable_fixed(); + #if IS_FXLIB==1 usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL }; usb_open(interfaces, GINT_CALL_NULL); + #endif prof_t perf_create, perf_project, perf_render; uint32_t time_create=0, time_project=0, time_render=0; prof_init(); - int nbInterestingSegments = (MAX_RENDER_DISTANCE / SEGMENT_LENGTH) + 10; // the number of segments to be projected considering the rendering distance + int nbInterestingSegments = (MAX_RENDER_DISTANCE / SEGMENT_LENGTH); // the number of segments to be projected considering the rendering distance - //-------------- - - initData( ); - - //-------------- perf_create = prof_make(); prof_enter(perf_create); - createCircuit(); - createClouds(); - prepareDecoration(); + initData( ); // Positioning of the Camera + createCircuit(); // Creates the circuit + createClouds(); // Creates the Sky and Clouds + createTraffic(); // Creates the cas + prepareDecoration(); // Prepares the multiple variations of Decoration (image scaling) + prepareTraffic(); // Prepares the multiple variations of Cars (image scaling) prof_leave(perf_create); time_create = prof_time(perf_create); @@ -171,7 +192,7 @@ int main(void) int indexstart = 0; int indexend = 0; - uint32_t maxDistance = (MAX_SEGMENT-nbInterestingSegments-5)*SEGMENT_LENGTH; + uint32_t maxDistance = (MAX_SEGMENT-nbInterestingSegments-1)*SEGMENT_LENGTH; uint32_t dt=0; uint16_t l=0; @@ -188,11 +209,8 @@ int main(void) indexstart = fround(cam->cZ) / SEGMENT_LENGTH; indexend = indexstart+nbInterestingSegments+1; - // there is an offset equals to 400 on z position - // this is to compute the first index of segment to be projected to screen - if (indexstart<0) indexstart=0; - if (indexstart>MAX_SEGMENT-nbInterestingSegments-1-2) indexstart=MAX_SEGMENT-nbInterestingSegments-1-2; + if (indexstart>MAX_SEGMENT-nbInterestingSegments-2) indexstart=MAX_SEGMENT-nbInterestingSegments-2; //-------------- @@ -200,14 +218,20 @@ int main(void) perf_project = prof_make(); prof_enter(perf_project); - //cam->cY = fix( 300 + interpolatePositionY(fround(cam->cZ)) ); - uint16_t cumulCurve=0; - for (int k=indexstart; k<=indexend; k++) // Need to project 1 more segment than actual drawing - { - projectCircuitFP( k ); - circuit[k]->CumulatedCurve = cumulCurve; - cumulCurve += circuit[k]->Curve; - } + + updateTraffic(); + + minYRoad = SCREEN_HEIGHT; + uint16_t cumulCurve=0; + for (int k=indexstart; k<=indexend; k++) // Need to project 1 more segment than actual drawing + { + projectCircuitFP( k ); + if (circuit[k]->YY; + circuit[k]->CumulatedCurve = cumulCurve; + cumulCurve += circuit[k]->Curve; + } + + prof_leave(perf_project); @@ -218,8 +242,14 @@ int main(void) perf_render = prof_make(); prof_enter(perf_render); - drawSky( ); - drawClouds( l % 396 ); + + drawSkyOptimised( DAY_BLUE_SKY ); + + if (BDrawClds) + { + drawClouds( l % 396 ); + } + cam->cY = fix( 300 ) + interpolatePositionY(fround(cam->cZ)); @@ -227,11 +257,33 @@ int main(void) { currentcurve = circuit[k]->CumulatedCurve; drawCircuitSegment( k ); - drawDecoration( k ); + if (BDrawDeco) drawDecoration( k ); } + if (BDrawCars) + for(int k=0; kwZ >= circuit[indexstart]->wZ && traffic[k]->wZ<=circuit[indexend]->wZ) + { + traffic[k]->visible = true; + drawTraffic( k ); + } + else traffic[k]->visible = false; + } + dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-48, &player, 257,1,72,46, DIMAGE_NONE); + #if 1 + dprint( 1, 210, C_WHITE, "Decs: %c", BDrawDeco==true?'Y':'N' ); // Key F1 + dprint( 67, 210, C_WHITE, "Clds: %c", BDrawClds==true?'Y':'N' ); // Key F2 + dprint( 133, 210, C_WHITE, "Cars: %c", BDrawCars==true?'Y':'N' ); // Key F3 + + dprint( 199, 210, C_WHITE, "DtR: %.1f", ((float) (time_render) / 1000.0) ); // Key F4 + dprint( 265, 210, C_WHITE, "ScrSht" ); // Key F5 + dprint( 331, 210, C_WHITE, "RecVid" ); // Key F6 + #endif // 1 + + #if 0 if (ShowDebug1) { Segment* currentSeg = circuit[indexstart]; @@ -264,20 +316,33 @@ int main(void) dprint( 1, 1, C_RED, "Crt=%.3D ms", time_create ); dprint( 1, 15, C_RED, "Prj=%.3D ms", time_project ); dprint( 1, 29, C_RED, "Rdr=%.3D ms", time_render ); + dprint( 1, 50, C_BLACK, "ISt_Z=%.1lf", circuit[indexstart]->wZ); + dprint( 1, 65, C_BLACK, "IEd_Z=%.1lf", circuit[indexend]->wZ); + /* for( int k=indexend-1; k>=indexstart; k--) { dprint( 100, 1+10*k-indexstart, C_WHITE, "S[%d]=%d", k, circuit[k]->DScale ); } + */ + /* for( int k=0; kX, nuages[k]->Y, nuages[k]->type ); } + */ + + for( int k=0; kvisible == true) dprint( 100, 1+10*k, C_BLACK, "Cr[%d]=%d-(%.2f,%.0lf,%d,%d)-(%d,%d,%d)", k, traffic[k]->DScale, traffic[k]->wX, traffic[k]->wZ, traffic[k]->Speed, traffic[k]->Type, traffic[k]->segnum, traffic[k]->X, traffic[k]->Y ); + else dprint( 100, 1+10*k, C_RED, "Cr[%d]=%d-(%.2f,%.0lf,%d,%d)-(%d,%d,%d)", k, traffic[k]->DScale, traffic[k]->wX, traffic[k]->wZ, traffic[k]->Speed, traffic[k]->Type, traffic[k]->segnum, traffic[k]->X, traffic[k]->Y ); + } } + #endif // 0 + - dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-48, &player, 257,1,72,46, DIMAGE_NONE); dupdate(); //r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT); @@ -285,7 +350,7 @@ int main(void) prof_leave(perf_render); time_render = prof_time(perf_render); - +#if IS_FXLIB==1 if (screenshot && usb_is_open()) { usb_fxlink_screenshot(true); @@ -296,19 +361,23 @@ int main(void) { usb_fxlink_videocapture(false); } +#endif l++; } prof_quit(); - usb_close(); +#if IS_FXLIB==1 + usb_close(); +#endif circuit.clear(); nuages.clear(); delete cam; freeDecoration(); + freeTraffic(); return 1; } diff --git a/src/parameters.h b/src/parameters.h index 0722682..65b8880 100644 --- a/src/parameters.h +++ b/src/parameters.h @@ -16,7 +16,14 @@ #define MAX_RENDER_DISTANCE 3000 + +#define NB_CLOUDS_SKY 10 +#define NB_CARS_TRAFFIC 10 + + #define std ustl +#define IS_FXLIB 1 + #endif // PARAMETERS_H diff --git a/src/src/cars.cc b/src/src/cars.cc new file mode 100644 index 0000000..f7e5a12 --- /dev/null +++ b/src/src/cars.cc @@ -0,0 +1,52 @@ +#include "../include/cars.h" +#include "../include/camera.h" + +#include +#include "../parameters.h" +#include "../include/circuit.h" + + + +Cars::Cars() +{ + //ctor +} + +Cars::~Cars() +{ + //dtor +} + +Cars::Cars( float x, double z, uint8_t s, uint8_t t ) +{ + wX = x; + wZ = z; + Speed = s; + Type = t; + X = 0; +} + +/* +void Cars::Project3DFP( camera* c ) +{ + fixed_t DX = (fix(wX*ROAD_WIDTH) - c->cX); + fixed_t DY = (interpolatePositionY( wZ ) - c->cY); + + fixed_t divDZ = fdiv( fix(1), (fixdouble(wZ) - c->cZ)); + fixed_t RW = fix(ROAD_WIDTH); + + fixed_t divAR = fdiv(fix(1), fixdouble(ASPECT_RATIO)); + + fixed_t Scale = fmul(fixdouble(DISTANCE_SCREEN), divDZ); + + fixed_t tempx = fmul(fmul(DX,Scale), divAR); + fixed_t tempy = fmul(DY, Scale); + + fixed_t sX=fmul(fix(SCREEN_CX), (fix(1)+tempx)); + fixed_t sY=fmul(fix(SCREEN_CY), (fix(1)-tempy)); + + X=fround(sX); + Y=fround(sY); +} +*/ + diff --git a/src/src/circuit.cc b/src/src/circuit.cc index 7a5fe64..82df2b4 100644 --- a/src/src/circuit.cc +++ b/src/src/circuit.cc @@ -2,6 +2,8 @@ #include "../include/segment.h" #include "../include/camera.h" #include "../include/clouds.h" +#include "../include/cars.h" + #include "../parameters.h" #include @@ -9,10 +11,13 @@ #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; @@ -25,7 +30,7 @@ extern bopti_image_t tree1, tree2, tree3; extern bopti_image_t sky1, sky2, sky3; bopti_image_t *scaledTrees[3][25] = { 0 }; - +bopti_image_t *scaledCars[3][25] = { 0 }; size_t image_size_profile(int profile, int width, int height) @@ -142,33 +147,27 @@ void createCircuit( void ) } */ - addStraightLine( L_VERYSHORT ); - addStraightLine( L_VERYSHORT ); - addCurve( L_SHORT, C_EASY, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_EASY, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_EASY, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); + addStraightLine( L_VERYSHORT, PLAINS ); + addStraightLine( L_VERYSHORT, 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 ); + addCurve( L_SHORT, C_HARD, RIGHT_CURVE, 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 ); + addHill( L_MEDIUM, H_BIG, UP_HILL, DESERT ); + addHill( L_MEDIUM, H_BIG, DOWN_HILL, DESERT ); + addCurve( L_SHORT, C_HARD, RIGHT_CURVE, PLAINS ); + addStraightLine( L_VERYLONG, PLAINS ); + addCurve( L_SHORT, C_HARD, LEFT_CURVE, PLAINS ); + addHill( L_MEDIUM, H_BIG, UP_HILL, PLAINS ); + addHill( L_MEDIUM, H_BIG, DOWN_HILL, PLAINS ); + addCurve( L_SHORT, C_HARD, RIGHT_CURVE, DESERT ); + addStraightLine( L_VERYLONG, DESERT ); }; @@ -176,10 +175,10 @@ void createClouds( void ) { srand( rtc_ticks() ); - for( int k = 0; k < 10; k++) + for( int k = 0; k < NB_CLOUDS_SKY; k++) { - int X = (rand() % 1188) - 396; - int Y = rand() % 80; + int X = (rand() % 792); + int Y = rand() % 60; int T = rand() % 3; Clouds* cl=new Clouds( X, Y, T ); @@ -188,7 +187,32 @@ void createClouds( void ) } -void addStraightLine( Length l ) +void createTraffic( void ) +{ + srand( rtc_ticks() ); + + for( int k = 0; k < NB_CARS_TRAFFIC; k++) + { + int8_t X = rand() % 4; + double Z = (double) (rand() % 10000); + uint8_t S = rand() % 4; + uint8_t T = rand() % 3; + + 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 addStraightLine( Length l, int8_t biome ) { double lastZ=0; int16_t lastY=0; @@ -212,11 +236,15 @@ void addStraightLine( Length l ) else if (deco==2) seg=new Segment( 0, lastY, lastZ + (i+1)*SEGMENT_LENGTH, 0, PALMTREE, -1 ); else if (deco==3) seg=new Segment( 0, lastY, lastZ + (i+1)*SEGMENT_LENGTH, 0, PALMTREE, DEADTREE ); - if (seg!=nullptr) circuit.push_back( seg ); + if (seg!=nullptr) + { + seg->environment = biome; + circuit.push_back( seg ); + } } } -void addCurve( Length l, CurveStrength s, CurveType t ) +void addCurve( Length l, CurveStrength s, CurveType t, int8_t biome ) { double lastZ=0; int16_t lastY=0; @@ -240,12 +268,16 @@ void addCurve( Length l, CurveStrength s, CurveType t ) else if (deco==2) seg=new Segment( 0, lastY, lastZ+(i+1)*SEGMENT_LENGTH, s*t, DEADTREE, -1 ); else if (deco==3) seg=new Segment( 0, lastY, lastZ+(i+1)*SEGMENT_LENGTH, s*t, DEADTREE, OAKTREE ); - if (seg!=nullptr) circuit.push_back( seg ); + if (seg!=nullptr) + { + seg->environment = biome; + circuit.push_back( seg ); + } } } -void addHill( Length l, HillSize s, HillType t ) +void addHill( Length l, HillSize s, HillType t, int8_t biome ) { double lastZ=0; int16_t lastY=0; @@ -268,7 +300,11 @@ void addHill( Length l, HillSize s, HillType t ) else if (deco==2) seg=new Segment( 0, lastY+(i+1)*t*s, lastZ+(i+1)*SEGMENT_LENGTH, 0, OAKTREE, -1 ); else if (deco==3) seg=new Segment( 0, lastY+(i+1)*t*s, lastZ+(i+1)*SEGMENT_LENGTH, 0, OAKTREE, PALMTREE ); - if (seg!=nullptr) circuit.push_back( seg ); + if (seg!=nullptr) + { + seg->environment = biome; + circuit.push_back( seg ); + } } } @@ -317,43 +353,59 @@ void drawCircuitSegment( uint16_t index ) if (Y1==Y2) return; - if (index%2==0) + if (circuit[index]->environment == PLAINS) { - drawGrass( Y2, Y1, 0, 255-shiftcolor, 45-shiftcolor ); + if (index%2==0) + { + //drawGrass( Y2, Y1, DARK_GREEN_GRASS ); - // route - drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 196-shiftcolor, 196-shiftcolor, 196-shiftcolor ); + drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, DARK_GREEN_GRASS ); - // ligne blanche centrale - drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); - // ligne blanche gauche - drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, LIGHT_GREY_ROAD ); - // ligne blanche centrale gauche - 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, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); + 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+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/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 ); - // ligne blanche centrale - drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); + drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, DARK_GREEN_GRASS ); + } + else + { + //drawGrass( Y2, Y1, LIGHT_GREEN_GRASS ); + drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, LIGHT_GREEN_GRASS ); - // ligne blanche centrale droite - 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, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); - - // ligne blanche droite - drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); + 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 + else if (circuit[index]->environment == DESERT) { - - drawGrass( Y2, Y1, 0, 255-shiftcolor, 0 ); - - drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 180-shiftcolor, 180-shiftcolor, 180-shiftcolor ); - // ligne rouge gauche - drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 0, 0 ); - // ligne rouge droite - drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 0, 0 ); - + if (index%2==0) + { + drawGrass( Y2, 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/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); + 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 ); + } + else + { + drawGrass( Y2, 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 ); + } } + } @@ -403,6 +455,12 @@ fixed_t interpolatePositionY( double currentZ ) } +uint16_t findIndex( double currentZ ) +{ + return (int) (currentZ / SEGMENT_LENGTH); +} + + void prepareDecoration( void ) { bopti_image_t const *src; @@ -413,6 +471,7 @@ void prepareDecoration( void ) for( int i=0; i<25; i++) { scale=2.0f/((float) (i+1)); + if(k==0) src = &tree1; else if(k==1) src = &tree2; else if(k==2) src = &tree3; @@ -420,7 +479,35 @@ void prepareDecoration( void ) int width = (int) ((float) src->width * scale); int height = (int) ((float) src->height * scale); scaledTrees[k][i] = resize(src, width, height); - //scale*=0.85f; + } + } +} + +void prepareTraffic( void ) +{ + bopti_image_t const *src; + + for( int k=0; k<3; k++) + { + float scale=1.0f; + for( int i=0; i<25; i++) + { + //scale=1.0f/((float) (i+1)); + if(k==0) src = &car1; + else if(k==1) src = &car2; + else if(k==2) src = &car3; + /* + else if(k==3) src = &car4; + else if(k==4) src = &car5; + else if(k==5) src = &car6; + else if(k==6) src = &car7; + else if(k==7) src = &car8; + */ + + int width = (int) ((float) src->width * scale); + int height = (int) ((float) src->height * scale); + scaledCars[k][i] = resize(src, width, height); + scale*=0.85; } } } @@ -428,8 +515,16 @@ void prepareDecoration( void ) void freeDecoration( void ) { - for( int k=0; k<3; k++) - for( int i=0; i<25; i++) + for( int k=0; k<3; k++) + for( int i=0; i<25; i++) + free(scaledTrees[k][i]); +} + + +void freeTraffic( void ) +{ + for( int k=0; k<3; k++) + for( int i=0; i<25; i++) free(scaledTrees[k][i]); } @@ -471,16 +566,57 @@ void drawDecoration( uint16_t index ) } +void updateTraffic( void ) +{ + for(int k=0; kwX += traffic[k]->Speed*dt; + } +} + + +void drawTraffic( uint16_t index ) +{ + bopti_image_t *image; + + int distance = fround(fdiv( (fixdouble(traffic[index]->wZ) - cam->cZ), fix(2*SEGMENT_LENGTH) )); + + int segnumber = findIndex( traffic[index]->wZ ); + traffic[index]->segnum = segnumber; + + if (distance<0) distance = 0; + else if (distance>24) distance = 24; + + traffic[index]->DScale = distance; + + image = scaledCars[traffic[index]->Type][distance]; + + int X = circuit[segnumber]->X + circuit[segnumber]->CumulatedCurve + traffic[index]->wX*circuit[segnumber]->W - image->width/2; + int Y = circuit[segnumber]->Y - image->height; + + traffic[index]->X = X; + traffic[index]->Y = Y; + + 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 if (nuages[k]->type==2) cloud=&sky3; + if (nuages[k]->Type==0) cloud=&sky1; + else if (nuages[k]->Type==1) cloud=&sky2; + else if (nuages[k]->Type==2) cloud=&sky3; - dimage( nuages[k]->X-offset, nuages[k]->Y, cloud ); + 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 ); } } + diff --git a/src/src/clouds.cc b/src/src/clouds.cc index e05a1f4..577f8ff 100644 --- a/src/src/clouds.cc +++ b/src/src/clouds.cc @@ -13,8 +13,7 @@ Clouds::~Clouds() Clouds::Clouds( int16_t x, int16_t y, int8_t t ) { - X = x; Y = y; - type = t; + Type = t; } diff --git a/src/src/drawstuff.cc b/src/src/drawstuff.cc index c934ba9..343b3be 100644 --- a/src/src/drawstuff.cc +++ b/src/src/drawstuff.cc @@ -1,8 +1,11 @@ #include "../include/drawstuff.h" #include "../parameters.h" #include +#include #include "../fixed.h" +extern uint8_t minYRoad; + void gint_dhline(int x1, int x2, int y, uint16_t color) { if((uint)y >= 224) return; @@ -34,6 +37,12 @@ void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B ) }; +void drawGrass( int y1, int y2, uint16_t color ) +{ + for (int y=y1; y<=y2; y++) gint_dhline( 0, SCREEN_WIDTH, y, color ); +}; + + void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B ) { @@ -63,11 +72,56 @@ void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, ui } }; + +void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint16_t color ) +{ + if (y1==y2) + { + gint_dhline( x1min, x1max, y1, color ); + return; + } + + fixed_t deltay = fdiv(fix(1), fix(y2-y1)); + + fixed_t xmin = fix(x1min); + fixed_t xmax = fix(x1max); + fixed_t dxmin = fix(x2min-x1min); + fixed_t dxmax = fix(x2max-x1max); + + for (int y=y1; y<=y2; y++) + { + if (y>0 && y