#include #include #include #include #include #include #include #include #include #include #include #include #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 extern bopti_image_t player; extern font_t speedfont, startseq; extern bopti_image_t speedhud; extern bopti_image_t flag, bigflag; int CurrentCircuitBiome = PLAINS; std::vector circuit; std::vector nuages; std::vector traffic; int MAX_SEGMENT=0; camera *cam; struct DataPerf { uint8_t update=0; uint8_t project=0; uint8_t render=0; }; #define MAXDATA 120 DataPerf GraphPerf[ MAXDATA ]; unsigned int DataIndex=0; 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; 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; } int my_profile(int key, int duration, int count) { // key: Key being repeated // duration: How long that key has been pressed // count: How many times it's been repeated already // Return value: how long to wait before next repeat (\B5s) // Only allow KEY_LEFT and KEY_RIGHT if(key!=KEY_LEFT && key!=KEY_RIGHT && key!=KEY_DOWN && key!=KEY_UP && key!=KEY_ALPHA && key!=KEY_SHIFT) return -1; // 500 ms for first repeat, 50 ms after that; stop after 10 repeats if(count == 0) return 500*1000; else return -1; } static void get_inputs( float dt, int index ) { CC = circuit[index]->Curve; CS = circuit[index]->Slope; key_event_t ev; while((ev = pollevent()).type != KEYEV_NONE) { } speedcontrol = false; viewside=0; if (CC<0) { viewside=-1; //cam->decX( CC*dt*speed/100 ); 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; //cam->decX( CC*dt*speed/100 ); 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(25.0); 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(25.0); 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_XOT)) { ShowDebug1 = false; ShowDebug2 = false; ShowDebug3 = false; } if(keydown(KEY_LOG)) { ShowDebug1 = true; ShowDebug2 = false; ShowDebug3 = false; } if(keydown(KEY_LN)) { ShowDebug1 = false; ShowDebug2 = true; ShowDebug3 = false; } if(keydown(KEY_SIN)) { ShowDebug1 = false; ShowDebug2 = false; ShowDebug3 = true; } if(keydown(KEY_F1)) BDrawDeco = !BDrawDeco; if(keydown(KEY_F2)) BDrawClds = !BDrawClds; if(keydown(KEY_F3)) BDrawCars = !BDrawCars; if(keydown(KEY_F4)) BDrawFPS = !BDrawFPS; if(keydown(KEY_F5)) screenshot = true; if(keydown(KEY_F6)) 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_XOT)) { ShowDebug1 = false; ShowDebug2 = false; ShowDebug3 = false; } if(keydown(KEY_LOG)) { ShowDebug1 = true; ShowDebug2 = false; ShowDebug3 = false; } if(keydown(KEY_LN)) { ShowDebug1 = false; ShowDebug2 = true; ShowDebug3 = false; } if(keydown(KEY_SIN)) { ShowDebug1 = false; ShowDebug2 = false; ShowDebug3 = true; } if(keydown(KEY_F1)) BDrawDeco = !BDrawDeco; if(keydown(KEY_F2)) BDrawClds = !BDrawClds; if(keydown(KEY_F3)) BDrawCars = !BDrawCars; if(keydown(KEY_F4)) BDrawFPS = !BDrawFPS; if(keydown(KEY_F5)) screenshot = true; if(keydown(KEY_F6)) 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 kmalloc_arena_t *_uram = kmalloc_get_arena("_uram"); kmalloc_gint_stats_t *_uram_stats; srand( rtc_ticks() ); prof_init(); drawStartTitle(); char texttosend[1024]; 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; int32_t start_time = 99000000; uint32_t score=99999; uint8_t stage=0; int8_t selectedCircuit=0; uint32_t time_update=0, time_create=0, time_project=0, time_render=0; exitToOS = false; stop = false; bool exitflag = false; do { exitflag = false; stage = drawMainMenu(); if (stage==0 || stage==1) { selectedCircuit = drawMenuCircuitSelect(); if (selectedCircuit != -1) exitflag=true; } else if (stage==2) { drawOptions(); } else if (stage==3) { drawCredit(); } else if (stage==4) { // Exit Menu TO BE DONE // quick and dirty exitToOS = true; exitflag=true; } } while (!exitflag); if (exitToOS==false) { stage = selectedCircuit; if (selectedCircuit==0) CurrentCircuitBiome = PLAINS; else if (selectedCircuit==1) CurrentCircuitBiome = DESERT; else if (selectedCircuit==2) CurrentCircuitBiome = USA; else if (selectedCircuit==3) CurrentCircuitBiome = FINLAND; else if (selectedCircuit==4) CurrentCircuitBiome = AFRICA; else if (selectedCircuit==5) CurrentCircuitBiome = PLAINS; else if (selectedCircuit==6) CurrentCircuitBiome = DESERT; else if (selectedCircuit==7) CurrentCircuitBiome = USA; else if (selectedCircuit==8) CurrentCircuitBiome = FINLAND; else if (selectedCircuit==9) CurrentCircuitBiome = AFRICA; else CurrentCircuitBiome = PLAINS; 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; putBillBoards(); createClouds(); // Creates the Sky and Clouds createTraffic( MAX_SEGMENT ); // Creates the cars prepareDecoration( CurrentCircuitBiome ); // 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); //-------------- 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 ? while (!stop) { 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 if (!SkipTime) { dt = ((float) (time_update+time_render+time_project) / 1000.0); } else { dt = 0; SkipTime=false; } if (initiateStart) { startCount -= dt*1000; startRemaining = ((float) (startCount) / 100000.0); } start_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) { updateTraffic( dt, maxDistance ); for (unsigned int k=0; kwZ / SEGMENT_LENGTH; if (CarSegment>=indexstart && CarSegmentvisible = 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; lCarList.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; lCarList.size(); l++ ) // For all cars inside that road segment { uint8_t indexCar = circuit[indexstart+1]->CarList[l]; if (traffic[indexCar]->wX>(roadpart-0.20f) && traffic[indexCar]->wX<(roadpart+0.20f) && traffic[indexCar]->SpeedY < minYRoad) // This is a trick to save precious time while drawing the Sky if (circuit[k]->Y <= minYRoad) minYRoad = circuit[k]->Y; circuit[k]->CumulatedCurve = cumulCurve; // This is the curve accumulated when we are drawing curves cumulCurve += circuit[k]->Curve; if (BDrawCars) for( unsigned int l=0; lCarList.size(); l++ ) // For all cars inside that road segment { uint8_t indexCar = circuit[k]->CarList[l]; traffic[indexCar]->Project3DFP( cam, k ); } } prof_leave(perf_project); time_project = prof_time(perf_project); //-------------- perf_render = prof_make(); prof_enter(perf_render); //if (BDrawBack) drawSkyOptimised( DAY_BLUE_SKY ); //else drawSkyFull( DAY_BLUE_SKY ); drawSkyOptimised( DAY_BLUE_SKY ); if (BDrawClds) { drawClouds( ); } if (BDrawBack) { drawFarBackground( deltaFarbackground, CurrentCircuitBiome ); drawNearBackground( deltaNearbackground, CurrentCircuitBiome ); } cam->cY = fix( 300+2*CS ) + interpolatePositionY(fround(cam->cZ) ); for( int k=indexend-1; k>=indexstart; k--) { currentcurve = circuit[k]->CumulatedCurve; drawCircuitSegment( k ); if (BDrawDeco) drawDecoration( k ); if (BDrawCars) for( unsigned int l=0; lCarList.size(); l++ ) // For all cars inside that road segment { uint8_t indexCar = circuit[k]->CarList[l]; drawTraffic( indexCar ); } if (BDrawCars) circuit[k]->CarList.clear(); } if (circuit[indexstart]->Special == CHECKPOINT && circuit[indexstart]->CheckValidated == false) { start_time+=60000000; circuit[indexstart]->CheckValidated = true; } else if (circuit[indexstart]->Special == FINISH && circuit[indexstart]->CheckValidated == false) { start_time+=60000000; circuit[indexstart]->CheckValidated = true; } else if (circuit[indexstart]->Special == START && circuit[indexstart]->CheckValidated == false) { start_time=99000000; circuit[indexstart]->CheckValidated = true; } // Draw a message when time is over if (start_time<=0) { failSequence=true; } int mod_base=20; int mod_comp=10; if (abs(speed)<1.0) mod_base = 30, mod_comp = 15; else if (abs(speed)<2.0) mod_base = 20, mod_comp = 10; else if (abs(speed)<3.0) mod_base = 16, mod_comp = 8; else if (abs(speed)<4.0) mod_base = 12, mod_comp = 6; else if (abs(speed)<5.0) mod_base = 8, mod_comp = 4; else mod_base = 4, mod_comp = 2; if ((speed==0) || (l%mod_base<=mod_comp)) // the small rick to have the speed impression on wheels and to have the correct view of the car during turns { if (viewside==-2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 99,1,80,46, DIMAGE_NONE); else if (viewside==-1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 181,1,74,46, DIMAGE_NONE); else if (viewside==0) dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-46, &player, 257,1,72,46, DIMAGE_NONE); else if (viewside==1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 331,1,74,46, DIMAGE_NONE); else if (viewside==2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 407,1,80,46, DIMAGE_NONE); } else { if (viewside==-2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 99,49,80,46, DIMAGE_NONE); else if (viewside==-1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 181,49,74,46, DIMAGE_NONE); else if (viewside==0) dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-46, &player, 257,49,72,46, DIMAGE_NONE); else if (viewside==1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 331,49,74,46, DIMAGE_NONE); else if (viewside==2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 407,49,80,46, DIMAGE_NONE); } score = fround(cam->cZ)/100; float drawspeed = (float) (speed*5.0f); dsubimage( 5, 5, &speedhud, 0, 117, 37, 13, DIMAGE_NONE); // speed logo dsubimage( 135, 5, &speedhud, 0, 130, 37, 13, DIMAGE_NONE); // timer logo dsubimage( 245, 5, &speedhud, 37, 117, 38, 13, DIMAGE_NONE); // speed logo dsubimage( 245, 25, &speedhud, 37, 130, 38, 13, DIMAGE_NONE); // timer logo dfont(&speedfont); if (drawspeed==0.0) { dprint_opt(122,3, C_RGB(0,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "0 :", drawspeed ); dprint_opt(120,1, C_RGB(255,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "0 :", drawspeed ); } else { dprint_opt(122,3, C_RGB(0,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.1f :", drawspeed ); dprint_opt(120,1, C_RGB(255,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.1f :", drawspeed ); //the ':' char corresponds to "Km/h" } dprint_opt(233,3, C_RGB(0,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D ;", remaining_time ); dprint_opt(230,1, C_RGB(255,255,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D ;", remaining_time ); // the ';' char corresponds to "s" dprint_opt(390,3, C_RGB(0,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D", score ); dprint_opt(388,1, C_RGB(255,255,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D", score ); // the ';' char corresponds to "s" dprint_opt(390,23, C_RGB(0,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D", stage ); dprint_opt(388,21, C_RGB(255,255,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D", stage ); // the ';' char corresponds to "s" if (drawspeed==0.0) dsubimage( 48, 25, &speedhud, 0, 0, 76, 13, DIMAGE_NONE); else if (drawspeed<3.30) dsubimage( 48, 25, &speedhud, 0, 13, 76, 13, DIMAGE_NONE); else if (drawspeed<6.70) dsubimage( 48, 25, &speedhud, 0, 26, 76, 13, DIMAGE_NONE); else if (drawspeed<10.0) dsubimage( 48, 25, &speedhud, 0, 39, 76, 13, DIMAGE_NONE); else if (drawspeed<13.3) dsubimage( 48, 25, &speedhud, 0, 52, 76, 13, DIMAGE_NONE); else if (drawspeed<16.7) dsubimage( 48, 25, &speedhud, 0, 65, 76, 13, DIMAGE_NONE); else if (drawspeed<20.0) dsubimage( 48, 25, &speedhud, 0, 78, 76, 13, DIMAGE_NONE); else if (drawspeed<23.3) dsubimage( 48, 25, &speedhud, 0, 91, 76, 13, DIMAGE_NONE); else dsubimage( 48, 25, &speedhud, 0, 104, 76, 13, DIMAGE_NONE); if (failSequence) { dimage( 198-bigflag.width/2, 112-bigflag.height/2, &bigflag ); dfont(&startseq); dprint_opt(200,108, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_BOTTOM, "YOU" ); dprint_opt(198,112, C_RGB(255,0,255), C_NONE, DTEXT_CENTER, DTEXT_BOTTOM, "YOU" ); dprint_opt(200,108, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_TOP, "LOOSE" ); dprint_opt(198,112, C_RGB(255,0,255), C_NONE, DTEXT_CENTER, DTEXT_TOP, "LOOSE" ); } if (initiateStart) // We are in the start sequence with the countdown { dfont(&startseq); if (startRemaining<54 && startRemaining>46) { dprint_opt(200,114, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">5<" ); dprint_opt(198,112, C_RGB(255,0,255), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">5<" ); } else if (startRemaining<44 && startRemaining>36) { dprint_opt(200,114, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">4<" ); dprint_opt(198,112, C_RGB(255,0,255), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">4<" ); } else if (startRemaining<34 && startRemaining>26) { dprint_opt(200,114, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">3<" ); dprint_opt(198,112, C_RGB(255,0,255), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">3<" ); } else if (startRemaining<24 && startRemaining>16) { dprint_opt(200,114, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">2<" ); dprint_opt(198,112, C_RGB(255,0,255), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">2<" ); } else if (startRemaining<14 && startRemaining>6) { dprint_opt(200,114, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">1<" ); dprint_opt(198,112, C_RGB(255,0,255), C_NONE, DTEXT_CENTER, DTEXT_CENTER, ">1<" ); } else if (startRemaining<4 && startRemaining>-4) { dimage( 198-bigflag.width/2, 112-bigflag.height/2, &bigflag ); } else if (startRemaining<-4) { start_time = 99000000; initiateStart=false; } } //dupdate(); //dprint( 3, 202, C_BLACK, "%.0f", dt ); //dprint( 1, 200, C_WHITE, "%.0f", dt ); if (BDrawFPS) { dfont(&speedfont); dsubimage( 5, 205, &speedhud, 0, 143, 27, 13, DIMAGE_NONE); // fps logo dprint_opt(42,202, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "%.0f <", (float) (1000.0f/dt) ); // the '>' symbol corresponds to "fps" dprint_opt(40,200, C_RGB(255,255,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "%.0f <", (float) (1000.0f/dt) ); GraphPerf[DataIndex].update = (uint8_t) (time_update/1000); GraphPerf[DataIndex].project = (uint8_t) (time_project/1000); GraphPerf[DataIndex].render = (uint8_t) (time_render/1000); DataIndex++; DataIndex = DataIndex % MAXDATA; dline( 249, 201, 375, 201, C_BLACK ); dline( 249, 202, 375, 202, C_BLACK ); dline( 249, 200-33, 375, 200-33, C_BLACK ); dline( 249, 200-40, 375, 200-40, C_BLACK ); dline( 249, 200-50, 375, 200-50, C_BLACK ); dline( 249, 201, 249, 100, C_BLACK ); dline( 248, 201, 248, 100, C_BLACK ); for( unsigned int k=0; kused_memory, _uram_stats->free_memory, _uram_stats->peak_used_memory); usb_fxlink_text(texttosend, 0); */ // Free all memory freeTraffic(); freeDecoration(); for(unsigned int i=0; i