# include <gint/display.h>
# include <gint/drivers/r61524.h>
# include <gint/rtc.h>
# include <gint/keyboard.h>
# include <gint/gint.h>
# include <gint/defs/types.h>
# include <fxlibc/printf.h>
# include <libprof.h>
# include <gint/usb.h>
# include <gint/usb-ff-bulk.h>
# include <math.h>
# include <vector>
# include "parameters.h"
# include "colors.h"
# include "include/camera.h"
# include "include/segment.h"
# include "include/circuit.h"
# include "include/drawstuff.h"
# include "include/clouds.h"
# include "include/cars.h"
# include "include/menus.h"
# include "include/saves.h"
# include <gint/kmalloc.h>
# include <stdio.h>
# define DEBUGXXX 0
extern bopti_image_t player ;
extern font_t speedfont , startseq , plate , autofont ;
extern bopti_image_t speedhud ;
extern bopti_image_t flag , bigflag ;
int CurrentCircuitBiome = PLAINS ;
std : : vector < Segment * > circuit ;
std : : vector < Clouds * > nuages ;
std : : vector < Cars * > traffic ;
int MAX_SEGMENT = 0 ;
camera * cam ;
char texttosend [ 1024 ] ;
int32_t start_time = 100000000 ;
uint32_t elapsed_time = 0 ;
uint32_t score = 0 ;
uint8_t stage = 0 , mode = 0 ;
int8_t selectedCircuit = 0 , secondvalidation = 0 ;
uint32_t time_update = 0 , time_create = 0 , time_project = 0 , time_render = 0 ;
uint8_t DiffLevel = 1 ;
uint8_t CarsNumb = 1 ;
char PlayerName [ 3 ] = { ' S ' , ' L ' , ' Y ' } ;
Parameters PlayerPara [ 1 ] ;
struct DataPerf
{
uint8_t update = 0 ;
uint8_t project = 0 ;
uint8_t render = 0 ;
} ;
extern bool saveexist ;
BestRanking HallOfFame [ 10 ] [ 5 ] ; // Table of score : 10 levels * 5 best scores
uint32_t FinalTime = 0 ;
bool skipranking = false ;
int ranking = - 1 ; // ranking is -1 if not ranked and between 1 and 5 if ranked
# define MAXDATA 120
DataPerf GraphPerf [ MAXDATA ] ;
unsigned int DataIndex = 0 ;
uint16_t NB_CARS_TRAFFIC = 200 ;
bool stop = false ;
bool exitToOS = false ;
bool record = false ;
bool screenshot = false ;
bool ShowDebug1 = false ;
bool ShowDebug2 = false ;
bool ShowDebug3 = false ;
bool BDrawDeco = true ;
bool BDrawClds = true ;
bool BDrawCars = true ;
bool BDrawBack = true ;
bool BDrawFPS = false ;
bool OptionMode = false ;
bool PauseMode = false ;
bool SkipTime = false ;
// for multilap
bool multilap = false ;
uint8_t numlap = 1 ;
uint8_t currentLap = 1 ;
uint16_t currentcurve = 0 ;
uint8_t shiftcolor = 0 ;
float speed = 0.0 ;
float maxspeedforward = 5.0 ;
float maxspeedbackward = 2.0 ;
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
int8_t viewside = 0 ;
int deltaFarbackground = 0 ;
int deltaNearbackground = 0 ;
int lastindex = 0 ;
int CC = 0 ; // current curve
int CS = 0 ;
void initEverything ( void )
{
CurrentCircuitBiome = PLAINS ;
circuit . clear ( ) ;
nuages . clear ( ) ;
traffic . clear ( ) ;
MAX_SEGMENT = 0 ;
DataIndex = 0 ;
stop = false ;
record = false ;
screenshot = false ;
ShowDebug1 = false ;
ShowDebug2 = false ;
ShowDebug3 = false ;
BDrawDeco = true ;
BDrawClds = true ;
BDrawCars = true ;
BDrawFPS = false ;
currentcurve = 0 ;
shiftcolor = 0 ;
speed = 0.0 ;
maxspeedforward = 5.0 ;
maxspeedbackward = 2.0 ;
direction = 1 ;
speedcontrol = false ;
minYRoad = 224 ; // We will track the upper Y (in fact the minimum Y during the RoadDrawing to optimize the rendering of the Sky
viewside = 0 ;
deltaFarbackground = 0 ;
deltaNearbackground = 0 ;
lastindex = 0 ;
CC = 0 ; // current curve
CS = 0 ;
multilap = false ;
numlap = 1 ;
currentLap = 1 ;
}
static void get_inputs ( float dt , int index )
{
CC = circuit [ index ] - > Curve ;
CS = circuit [ index ] - > Slope ;
maxspeedforward = 5.0 - ( ( ( float ) CS ) / 100.0f ) + ( ( ( float ) CC ) * f2float ( cam - > cX ) / ROAD_WIDTH / 20.0f ) ;
key_event_t ev ;
while ( ( ev = pollevent ( ) ) . type ! = KEYEV_NONE )
{
}
speedcontrol = false ;
viewside = 0 ;
if ( CC < 0 )
{
viewside = - 1 ;
if ( CurrentCircuitBiome = = FINLAND ) cam - > decX ( CC * dt * speed / 50 ) ; // very hard to turn in Finland with snow
else if ( CurrentCircuitBiome = = AFRICA ) cam - > decX ( CC * dt * speed / 75 ) ; // hard in Africa with dirt
else cam - > decX ( CC * dt * speed / 100 ) ; // more easy on normal roads
}
else if ( CC > 0 )
{
viewside = + 1 ;
if ( CurrentCircuitBiome = = FINLAND ) cam - > decX ( CC * dt * speed / 50 ) ; // very hard to turn in Finland with snow
else if ( CurrentCircuitBiome = = AFRICA ) cam - > decX ( CC * dt * speed / 75 ) ; // hard in Africa with dirt
else cam - > decX ( CC * dt * speed / 100 ) ; // more easy on normal roads
}
if ( keydown ( KEY_LEFT ) )
{
cam - > decX ( 5.0 * speed * direction ) ;
viewside = - 1 ;
if ( CC < 0 ) viewside = - 2 ; // We are in a curve and turning
if ( CC > 0 ) viewside = 0 ;
}
if ( keydown ( KEY_RIGHT ) )
{
cam - > incX ( 5.0 * speed * direction ) ;
viewside = 1 ;
if ( CC > 0 ) viewside = + 2 ;
if ( CC < 0 ) viewside = 0 ;
}
if ( keydown ( KEY_SHIFT ) ) // Accelerates
{
if ( direction = = - 1 & & speed > 0 )
{
direction = - 1 ;
speed - = 0.5 ;
if ( speed < 0 ) speed = 0 ;
cam - > decZ ( speed * dt ) ;
}
else
{
direction = 1 ;
speed + = 0.05 ;
if ( speed > maxspeedforward ) speed = maxspeedforward ;
cam - > incZ ( speed * dt ) ;
}
speedcontrol = true ;
}
if ( keydown ( KEY_ALPHA ) ) // breaks or rear if speed <0
{
if ( direction = = 1 & & speed > 0 )
{
direction = 1 ;
speed - = 0.5 ;
if ( speed < 0 ) speed = 0 ;
cam - > incZ ( speed * dt ) ;
}
else
{
direction = - 1 ;
speed + = 0.025 ;
if ( speed > maxspeedbackward ) speed = maxspeedbackward ;
cam - > decZ ( speed * dt ) ;
}
speedcontrol = true ;
}
if ( keydown ( KEY_EXIT ) ) drawPauseQuit ( ) ;
if ( keydown ( KEY_OPTN ) ) drawOptions ( ) ;
# if IS_FXLIB==1
if ( keydown ( KEY_F1 ) ) BDrawDeco = ! BDrawDeco ;
if ( keydown ( KEY_F2 ) ) BDrawClds = ! BDrawClds ;
if ( keydown ( KEY_F3 ) ) BDrawCars = ! BDrawCars ;
if ( keydown ( KEY_F4 ) ) BDrawBack = ! BDrawBack ;
if ( keydown ( KEY_F5 ) ) BDrawFPS = ! BDrawFPS ;
if ( keydown ( KEY_7 ) ) screenshot = true ;
if ( keydown ( KEY_8 ) ) record = ! record ;
# endif // IS_FXLIB
if ( speedcontrol = = false )
{
speed - = 0.1 ;
if ( speed < 0 ) speed = 0 ;
if ( direction = = 1 )
cam - > incZ ( speed * dt ) ;
else
cam - > decZ ( speed * dt ) ;
}
// Adjust position of the background
if ( lastindex ! = index )
{
deltaFarbackground - = CC * speed * dt / 250 ;
deltaNearbackground - = CC * speed * dt / 100 ;
}
lastindex = index ;
// adjust speed if we drive on the side of the road
if ( fround ( cam - > cX ) < - 1 * ROAD_WIDTH & & speed > 2.0 ) speed = 2.0 ;
if ( fround ( cam - > cX ) > ROAD_WIDTH & & speed > 2.0 ) speed = 2.0 ;
if ( fround ( cam - > cX ) < - 1.35 * ROAD_WIDTH & & speed > 0.0 )
{
speed = 0.0 ;
cam - > cX = fix ( - 0.0 * ROAD_WIDTH ) ; //set the car in the center of the road (was formerly -0.75)
}
if ( fround ( cam - > cX ) > 1.35 * ROAD_WIDTH & & speed > 0.0 )
{
speed = 0.0 ;
cam - > cX = fix ( 0.0 * ROAD_WIDTH ) ; //set the car in the center of the road (was formerly 0.75)
}
}
static void get_minimum_inputs ( void )
{
key_event_t ev ;
while ( ( ev = pollevent ( ) ) . type ! = KEYEV_NONE )
{
}
if ( keydown ( KEY_EXIT ) ) drawPauseQuit ( ) ;
if ( keydown ( KEY_OPTN ) ) drawOptions ( ) ;
# if IS_FXLIB==1
if ( keydown ( KEY_F1 ) ) BDrawDeco = ! BDrawDeco ;
if ( keydown ( KEY_F2 ) ) BDrawClds = ! BDrawClds ;
if ( keydown ( KEY_F3 ) ) BDrawCars = ! BDrawCars ;
if ( keydown ( KEY_F4 ) ) BDrawBack = ! BDrawBack ;
if ( keydown ( KEY_F5 ) ) BDrawFPS = ! BDrawFPS ;
if ( keydown ( KEY_7 ) ) screenshot = true ;
if ( keydown ( KEY_8 ) ) record = ! record ;
# endif // IS_FXLIB
}
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
gint_world_switch ( GINT_CALL ( is_save_existing ) ) ;
if ( ! saveexist ) // if we do not have saves
gint_world_switch ( GINT_CALL ( saveprogress ) ) ; // we create a progress file which is empty
gint_world_switch ( GINT_CALL ( loadprogress ) ) ; // then we load it
gint_world_switch ( GINT_CALL ( is_param_existing ) ) ;
if ( ! saveexist ) // if we do not have saves
gint_world_switch ( GINT_CALL ( saveparameters ) ) ; // we create a progress file which is empty
gint_world_switch ( GINT_CALL ( loadparameters ) ) ; // then we load it
DiffLevel = PlayerPara [ 0 ] . DiffLevel ;
CarsNumb = PlayerPara [ 0 ] . CarsNumb ;
PlayerName [ 0 ] = PlayerPara [ 0 ] . PlayerName [ 0 ] ;
PlayerName [ 1 ] = PlayerPara [ 0 ] . PlayerName [ 1 ] ;
PlayerName [ 2 ] = PlayerPara [ 0 ] . PlayerName [ 2 ] ;
kmalloc_arena_t * _uram = kmalloc_get_arena ( " _uram " ) ;
kmalloc_gint_stats_t * _uram_stats ;
/* allow more RAM */
char const * osv = ( char * ) 0x80020020 ;
static kmalloc_arena_t extended_ram = { 0 } ;
kmalloc_gint_stats_t * extram_stats ;
bool canWeAllocate3Mb = false ;
if ( ( ! strncmp ( osv , " 03. " , 3 ) & & osv [ 3 ] < = ' 6 ' ) & & gint [ HWCALC ] = = HWCALC_FXCG50 ) // CG-50
{
extended_ram . name = " extram " ;
extended_ram . is_default = true ;
extended_ram . start = ( void * ) 0x8c200000 ;
extended_ram . end = ( void * ) 0x8c500000 ;
kmalloc_init_arena ( & extended_ram , true ) ;
kmalloc_add_arena ( & extended_ram ) ;
canWeAllocate3Mb = true ;
}
else if ( gint [ HWCALC ] = = HWCALC_PRIZM ) // CG-10/20
{
extended_ram . name = " extram " ;
extended_ram . is_default = true ;
uint16_t * vram1 , * vram2 ;
dgetvram ( & vram1 , & vram2 ) ;
dsetvram ( vram1 , vram1 ) ;
extended_ram . start = vram2 ;
extended_ram . end = ( char * ) vram2 + 396 * 224 * 2 ;
kmalloc_init_arena ( & extended_ram , true ) ;
kmalloc_add_arena ( & extended_ram ) ;
canWeAllocate3Mb = false ;
}
else if ( gint [ HWCALC ] = = HWCALC_FXCG_MANAGER ) // CG-50 EMULATOR
{
extended_ram . name = " extram " ;
extended_ram . is_default = true ;
extended_ram . start = ( void * ) 0x88200000 ;
extended_ram . end = ( void * ) 0x88500000 ;
kmalloc_init_arena ( & extended_ram , true ) ;
kmalloc_add_arena ( & extended_ram ) ;
canWeAllocate3Mb = true ;
}
else abort ( ) ;
srand ( rtc_ticks ( ) ) ;
prof_init ( ) ;
drawStartTitle ( ) ;
exitToOS = false ;
do
{
/*
_uram_stats = kmalloc_get_gint_stats ( _uram ) ;
sprintf ( texttosend , " [Begining of loop] Memory Status - Used: %d - Free: %d - Peak Used: %d " , _uram_stats - > used_memory , _uram_stats - > free_memory , _uram_stats - > peak_used_memory ) ;
usb_fxlink_text ( texttosend , 0 ) ;
*/
// Try to restart from very begining
initEverything ( ) ;
prof_t perf_update , perf_create , perf_project , perf_render ;
start_time = 100000000 ;
elapsed_time = 0 ;
score = 0 ;
stage = 0 ;
mode = 0 ;
selectedCircuit = 0 ;
secondvalidation = 0 ;
time_update = 0 ;
time_create = 0 ;
time_project = 0 ;
time_render = 0 ;
ranking = - 1 ;
exitToOS = false ;
stop = false ;
bool exitflag = false ;
do
{
exitflag = false ;
mode = drawMainMenu ( ) ;
if ( mode = = 0 )
{
selectedCircuit = drawMenuCircuitSelect ( ) ;
if ( selectedCircuit ! = - 1 ) secondvalidation = drawMenuCircuitDetails ( selectedCircuit ) ;
if ( selectedCircuit ! = - 1 & & secondvalidation ! = - 1 ) exitflag = true ;
}
else if ( mode = = 1 )
{
selectedCircuit = drawMenuCircuitSelect ( ) ;
if ( selectedCircuit ! = - 1 ) secondvalidation = drawMenuCircuitDetails ( selectedCircuit ) ;
if ( selectedCircuit ! = - 1 & & secondvalidation ! = - 1 ) secondvalidation = drawMenuBestTime ( selectedCircuit ) ;
if ( selectedCircuit ! = - 1 & & secondvalidation ! = - 1 ) exitflag = true ;
}
else if ( mode = = 2 )
{
drawGameOptions ( ) ;
PlayerPara [ 0 ] . DiffLevel = DiffLevel ;
PlayerPara [ 0 ] . CarsNumb = CarsNumb ;
PlayerPara [ 0 ] . PlayerName [ 0 ] = PlayerName [ 0 ] ;
PlayerPara [ 0 ] . PlayerName [ 1 ] = PlayerName [ 1 ] ;
PlayerPara [ 0 ] . PlayerName [ 2 ] = PlayerName [ 2 ] ;
gint_world_switch ( GINT_CALL ( saveparameters ) ) ;
}
else if ( mode = = 3 )
{
drawOptions ( ) ;
}
else if ( mode = = 4 )
{
drawCredit ( ) ;
}
else if ( mode = = 5 )
{
exitToOS = true ;
exitflag = true ;
}
}
while ( ! exitflag ) ;
skipranking = false ;
if ( ! exitToOS )
{
//stage = selectedCircuit;
if ( selectedCircuit = = 0 ) CurrentCircuitBiome = PLAINS , multilap = false , currentLap = 1 , numlap = 1 ;
else if ( selectedCircuit = = 1 ) CurrentCircuitBiome = DESERT , multilap = false , currentLap = 1 , numlap = 1 ;
else if ( selectedCircuit = = 2 ) CurrentCircuitBiome = USA , multilap = false , currentLap = 1 , numlap = 1 ;
else if ( selectedCircuit = = 3 ) CurrentCircuitBiome = FINLAND , multilap = false , currentLap = 1 , numlap = 1 ;
else if ( selectedCircuit = = 4 ) CurrentCircuitBiome = AFRICA , multilap = false , currentLap = 1 , numlap = 1 ;
else if ( selectedCircuit = = 5 ) CurrentCircuitBiome = PLAINS , multilap = true , currentLap = 1 , numlap = 3 ;
else if ( selectedCircuit = = 6 ) CurrentCircuitBiome = DESERT , multilap = true , currentLap = 1 , numlap = 3 ;
else if ( selectedCircuit = = 7 ) CurrentCircuitBiome = USA , multilap = true , currentLap = 1 , numlap = 3 ;
else if ( selectedCircuit = = 8 ) CurrentCircuitBiome = FINLAND , multilap = true , currentLap = 1 , numlap = 3 ;
else if ( selectedCircuit = = 9 ) CurrentCircuitBiome = AFRICA , multilap = true , currentLap = 1 , numlap = 3 ;
else CurrentCircuitBiome = PLAINS , multilap = false , currentLap = 1 , numlap = 1 ;
int nbInterestingSegments = ( MAX_RENDER_DISTANCE / SEGMENT_LENGTH ) ; // the number of segments to be projected considering the rendering distance
perf_create = prof_make ( ) ;
prof_enter ( perf_create ) ;
initData ( ) ; // Positioning of the Camera
createCircuit ( selectedCircuit ) ; // Creates the circuit
MAX_SEGMENT = circuit . size ( ) ;
//uint32_t maxDistance = (MAX_SEGMENT-nbInterestingSegments-5)*SEGMENT_LENGTH;
double maxDistance = ( double ) ( ( MAX_SEGMENT - 1 ) * SEGMENT_LENGTH ) ;
putBillBoards ( ) ;
createClouds ( ) ; // Creates the Sky and Clouds
if ( mode = = 0 )
{
// linear circuits needs many cars
if ( selectedCircuit > = 0 & & selectedCircuit < = 3 )
{
if ( CarsNumb = = 0 ) NB_CARS_TRAFFIC = 50 ;
else if ( CarsNumb = = 1 ) NB_CARS_TRAFFIC = 100 ;
else if ( CarsNumb = = 2 ) NB_CARS_TRAFFIC = 200 ;
else if ( CarsNumb = = 3 ) NB_CARS_TRAFFIC = 300 ;
else NB_CARS_TRAFFIC = 100 ;
}
/* else if (selectedCircuit==4) // except for Africa which is very heavy so we need more memory
{
if ( CarsNumb = = 0 ) NB_CARS_TRAFFIC = 50 ;
else if ( CarsNumb = = 1 ) NB_CARS_TRAFFIC = 75 ;
else if ( CarsNumb = = 2 ) NB_CARS_TRAFFIC = 100 ;
else if ( CarsNumb = = 3 ) NB_CARS_TRAFFIC = 150 ;
else NB_CARS_TRAFFIC = 75 ;
}
*/
else // while circular needs much less
{
if ( CarsNumb = = 0 ) NB_CARS_TRAFFIC = 25 ;
else if ( CarsNumb = = 1 ) NB_CARS_TRAFFIC = 50 ;
else if ( CarsNumb = = 2 ) NB_CARS_TRAFFIC = 100 ;
else if ( CarsNumb = = 3 ) NB_CARS_TRAFFIC = 150 ;
else NB_CARS_TRAFFIC = 10 ;
}
createTraffic ( MAX_SEGMENT ) ; // Creates the cars
prepareTraffic ( ) ; // Prepares the multiple variations of Cars (image scaling)
}
prepareDecoration ( CurrentCircuitBiome ) ; // Prepares the multiple variations of Decoration (image scaling)
# if DEBUGXXX==1
_uram_stats = kmalloc_get_gint_stats ( _uram ) ;
extram_stats = kmalloc_get_gint_stats ( & extended_ram ) ;
sprintf ( texttosend , " [_U RAM] Memory Status - Used: %d - Free: %d - Peak Used: %d " , _uram_stats - > used_memory , _uram_stats - > free_memory , _uram_stats - > peak_used_memory ) ;
if ( usb_is_open ( ) ) usb_fxlink_text ( texttosend , 0 ) ;
sprintf ( texttosend , " [EXT RAM] Memory Status - Used: %d - Free: %d - Peak Used: %d " , extram_stats - > used_memory , extram_stats - > free_memory , extram_stats - > peak_used_memory ) ;
if ( usb_is_open ( ) ) usb_fxlink_text ( texttosend , 0 ) ;
# endif // DEBUGXXX
prof_leave ( perf_create ) ;
time_create = prof_time ( perf_create ) ;
//--------------
int indexstart = 0 ;
int indexend = 0 ;
float dt = 0 ;
uint16_t l = 0 ;
uint32_t remaining_time ;
DataIndex = 0 ;
bool initiateStart = true ; // are we in the start sequence ?
int32_t startCount = 6000000 ;
int32_t startRemaining ;
bool finishSequence = false ; // Did we reached the end of the race ?
bool failSequence = false ; // Did we run out of time ?
bool stopcounting = false ;
while ( ! stop )
{
//new position
if ( ! SkipTime )
{
dt = ( ( float ) ( time_update + time_render + time_project ) / 1000.0 ) ;
}
else
{
dt = 0 ;
SkipTime = false ;
}
perf_update = prof_make ( ) ;
prof_enter ( perf_update ) ;
if ( ! initiateStart & & ! finishSequence & & ! failSequence ) get_inputs ( dt , indexstart ) ; // The racer is not started : no need to get inputs and we are not in fail or finish sequence
else get_minimum_inputs ( ) ; // the we can just have minimum inputs
//former position
if ( initiateStart )
{
startCount - = dt * 1000 ;
startRemaining = ( ( float ) ( startCount ) / 100000.0 ) ;
}
if ( ! stopcounting ) start_time - = dt * 1000 ;
if ( ! stopcounting ) elapsed_time + = dt * 1000 ;
if ( start_time < 0 ) start_time = 0 ;
remaining_time = ( ( float ) ( start_time ) / 1000000.0 ) ;
//--------------
if ( fround ( cam - > cZ ) < = 0 ) cam - > cZ = fixdouble ( 0.0 ) ;
//if (fround(cam->cZ)>=maxDistance) cam->cZ=fixdouble(maxDistance);
indexstart = fround ( cam - > cZ ) / SEGMENT_LENGTH ;
if ( indexstart < 0 ) indexstart = 0 ;
indexend = indexstart + nbInterestingSegments + 1 ;
//if (indexstart>MAX_SEGMENT-nbInterestingSegments-2) indexstart=MAX_SEGMENT-nbInterestingSegments-2;
prof_leave ( perf_update ) ;
time_update = prof_time ( perf_update ) ;
//--------------
perf_project = prof_make ( ) ;
prof_enter ( perf_project ) ;
minYRoad = SCREEN_HEIGHT ;
if ( BDrawCars & & mode = = 0 )
{
updateTraffic ( dt , maxDistance ) ;
for ( unsigned int k = 0 ; k < traffic . size ( ) ; k + + ) // Need to project 1 more segment than actual drawing
{
uint16_t CarSegment = traffic [ k ] - > wZ / SEGMENT_LENGTH ;
if ( CarSegment > = indexstart & & CarSegment < indexend )
{
//traffic[k]->visible = true;
circuit [ CarSegment ] - > CarList . push_back ( k ) ;
}
//else
//traffic[k]->visible = false;
}
float roadpart = f2float ( cam - > cX ) / ( float ) ROAD_WIDTH ;
// Update car positions : car with higher speed change line not to collide with player
for ( unsigned int l = 0 ; l < circuit [ indexstart ] - > CarList . size ( ) ; l + + ) // For all cars inside that road segment
{
uint8_t indexCar = circuit [ indexstart ] - > CarList [ l ] ;
if ( traffic [ indexCar ] - > wX > ( roadpart - 0.25f ) & & traffic [ indexCar ] - > wX < ( roadpart + 0.25f ) & & traffic [ indexCar ] - > Speed > speed )
{
if ( traffic [ indexCar ] - > wX > = - 0.25 ) traffic [ indexCar ] - > wX - = 0.5 ; // if we are on one of the most right lanes, we overtake by the left
else traffic [ indexCar ] - > wX < - 0.25 ; // else we change to the lane on the right
}
}
for ( unsigned int l = 0 ; l < circuit [ indexstart + 1 ] - > CarList . size ( ) ; l + + ) // For all cars inside that road segment
{
uint8_t indexCar = circuit [ indexstart + 1 ] - > CarList [ l ] ;
if ( traffic [ indexCar ] - > wX > ( roadpart - 0.22f ) & & traffic [ indexCar ] - > wX < ( roadpart + 0.22f ) & & traffic [ indexCar ] - > Speed < speed )
{
speed = traffic [ indexCar ] - > Speed - 0.5 ;
score = max ( 0 , score - 250 ) ;
}
}
if ( DiffLevel > = 1 ) // Normal or Hard : cars can overtake the other opponents
{
for ( unsigned int k = indexstart ; k < indexend ; k + + )
{
for ( unsigned int l = 0 ; l < circuit [ k ] - > CarList . size ( ) ; l + + ) // For all cars inside that road segment
{
uint8_t indexCar = circuit [ k ] - > CarList [ l ] ;
for ( unsigned int m = 0 ; m < circuit [ k + 1 ] - > CarList . size ( ) ; m + + )
{