diff --git a/CMakeLists.txt b/CMakeLists.txt index e75b7e7..c0359e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(SOURCES src/src/clouds.cc src/src/cars.cc src/src/menus.cc + src/src/saves.cc src/src/utils.cc ) diff --git a/CppOutRun.cbp b/CppOutRun.cbp index ff6da79..be0a7d4 100644 --- a/CppOutRun.cbp +++ b/CppOutRun.cbp @@ -37,6 +37,7 @@ + @@ -47,6 +48,7 @@ + diff --git a/CppOutRun.layout b/CppOutRun.layout index 9f99b77..28ad034 100644 --- a/CppOutRun.layout +++ b/CppOutRun.layout @@ -2,102 +2,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -105,32 +12,76 @@ - - - - - - - - - - - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -143,19 +94,79 @@ + + + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fxlink-image-2022.02.28-23h13-6.png b/fxlink-image-2022.02.28-23h13-6.png new file mode 100644 index 0000000..344a4ab Binary files /dev/null and b/fxlink-image-2022.02.28-23h13-6.png differ diff --git a/fxlink-image-2022.02.28-23h14-21.png b/fxlink-image-2022.02.28-23h14-21.png new file mode 100644 index 0000000..8dcf267 Binary files /dev/null and b/fxlink-image-2022.02.28-23h14-21.png differ diff --git a/src/include/menus.h b/src/include/menus.h index 2e34ca5..d9512e9 100644 --- a/src/include/menus.h +++ b/src/include/menus.h @@ -27,4 +27,7 @@ void getInputPauseQuit( void ); int drawMenuCircuitDetails( int circuit, int mode ); void getInputCircuitDetails( void ); +int drawMenuBestTime( int circuit ); +void getInputBestTime( void ); + #endif // MENUS_H diff --git a/src/include/saves.h b/src/include/saves.h new file mode 100644 index 0000000..4f19869 --- /dev/null +++ b/src/include/saves.h @@ -0,0 +1,16 @@ +#include + + +struct BestRanking +{ + char playerName[3] = { '.', '.', '.' }; // name of the player + char padding = 'Z'; // toi tu m'auras fait me gratter la tête !! Mon cochon. + uint32_t bestScore = 9999; + uint32_t bestTime = 9999; +}; + + +void is_save_existing( void ); +void saveprogress( void ); +void loadprogress( void ); + diff --git a/src/main.cc b/src/main.cc index bbb292b..beab657 100644 --- a/src/main.cc +++ b/src/main.cc @@ -25,11 +25,13 @@ #include "include/cars.h" #include "include/menus.h" +#include "include/saves.h" + #include #include -#define DEBUGXXX 0 +#define DEBUGXXX 1 extern bopti_image_t player; @@ -45,10 +47,19 @@ std::vector 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] = "SLY"; +char PlayerName[3] = { 'S', 'L', 'Y' }; struct DataPerf { @@ -57,11 +68,16 @@ struct DataPerf 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; + #define MAXDATA 120 DataPerf GraphPerf[ MAXDATA ]; unsigned int DataIndex=0; -uint8_t NB_CARS_TRAFFIC=200; +uint16_t NB_CARS_TRAFFIC=200; bool stop = false; bool exitToOS = false; @@ -346,6 +362,18 @@ int main(void) #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 + + + + kmalloc_arena_t *_uram = kmalloc_get_arena("_uram"); kmalloc_gint_stats_t *_uram_stats; @@ -355,20 +383,39 @@ int main(void) static kmalloc_arena_t extended_ram = { 0 }; kmalloc_gint_stats_t *extram_stats; - bool canWeAllocateMore = false; + bool canWeAllocate3Mb = false; - if(!strncmp(osv, "03.", 3) && osv[3] <= '6') + + if((!strncmp(osv, "03.", 3) && osv[3] <= '6') && gint[HWCALC] == HWCALC_FXCG50) { extended_ram.name = "extram"; - extended_ram.is_default = true; // Je suis pas sûr de ça, j'imagine que mettre true veut dire utilisation exclusive de "_extram" + extended_ram.is_default = true; extended_ram.start = (void *)0x8c200000; - extended_ram.end = (void *)0x8c500000 ; // 0x8c200000 + 0x00300000 correspondant à 3Mo + extended_ram.end = (void *)0x8c500000 ; - kmalloc_init_arena(&extended_ram , true); + kmalloc_init_arena(&extended_ram, true); kmalloc_add_arena(&extended_ram ); - canWeAllocateMore = true; + canWeAllocate3Mb = true; } + else if (gint[HWCALC] == HWCALC_PRIZM) + { + 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 abort(); srand( rtc_ticks() ); @@ -380,8 +427,6 @@ int main(void) drawStartTitle(); - char texttosend[1024]; - exitToOS = false; @@ -398,12 +443,17 @@ int main(void) initEverything(); prof_t perf_update, perf_create, perf_project, perf_render; - 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; + 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; exitToOS = false; @@ -429,6 +479,7 @@ int main(void) selectedCircuit = drawMenuCircuitSelect(); if (selectedCircuit != -1) secondvalidation = drawMenuCircuitDetails( selectedCircuit, 1 ); + if (selectedCircuit != -1 && secondvalidation != -1) secondvalidation = drawMenuBestTime( selectedCircuit ); if (selectedCircuit != -1 && secondvalidation != -1) exitflag=true; } else if (mode==2) @@ -451,6 +502,8 @@ int main(void) } while (!exitflag); + skipranking = false; + if (!exitToOS) { //stage = selectedCircuit; @@ -492,26 +545,26 @@ int main(void) // linear circuits needs many cars if (selectedCircuit>=0 && selectedCircuit<=3) { - if (CarsNumb==0) NB_CARS_TRAFFIC=100; - else if (CarsNumb==1) NB_CARS_TRAFFIC=200; - else if (CarsNumb==2) NB_CARS_TRAFFIC=500; - else if (CarsNumb==3) NB_CARS_TRAFFIC=1000; + 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 + /* 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=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=10; - else if (CarsNumb==1) NB_CARS_TRAFFIC=20; - else if (CarsNumb==2) NB_CARS_TRAFFIC=50; - else if (CarsNumb==3) NB_CARS_TRAFFIC=100; + if (CarsNumb==0) NB_CARS_TRAFFIC=5; + else if (CarsNumb==1) NB_CARS_TRAFFIC=10; + else if (CarsNumb==2) NB_CARS_TRAFFIC=20; + else if (CarsNumb==3) NB_CARS_TRAFFIC=30; else NB_CARS_TRAFFIC=10; } @@ -861,6 +914,7 @@ int main(void) circuit[indexstart]->CheckValidated = true; score+=20000; finishSequence=true; + FinalTime = elapsed_time/1000000; } #if DEBUGXXX==1 if (usb_is_open()) @@ -898,7 +952,7 @@ int main(void) // Draw a message when time is over - if (start_time<=0) + if (start_time<=0 && mode == 0) { failSequence=true; } @@ -965,8 +1019,17 @@ int main(void) 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(231,1, C_RGB(255,255,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D ;", remaining_time ); // the ';' char corresponds to "s" + if (mode==0) + { + dprint_opt(233,3, C_RGB(0,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D ;", remaining_time ); + dprint_opt(231,1, C_RGB(255,255,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D ;", remaining_time ); // the ';' char corresponds to "s" + } + else if (mode==1) + { + dprint_opt(233,3, C_RGB(0,0,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D ;", elapsed_time/1000000 ); + dprint_opt(231,1, C_RGB(255,255,0), C_NONE, DTEXT_RIGHT, DTEXT_TOP, "%.3D ;", elapsed_time/1000000 ); // 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" @@ -1009,6 +1072,59 @@ int main(void) dprint_opt(200,108, C_RGB(0,0,0), C_NONE, DTEXT_CENTER, DTEXT_TOP, "WIN" ); dprint_opt(198,112, C_RGB(0,255,0), C_NONE, DTEXT_CENTER, DTEXT_TOP, "WIN" ); + + if (mode==1 && !skipranking) + { + +#if DEBUGXXX==1 + if (usb_is_open()) usb_fxlink_text("save perf", 0); +#endif + + bool donerank = false; + int k=0; + + while (!donerank && k<5) + { + +#if DEBUGXXX==1 + if (usb_is_open()) usb_fxlink_text("in the loop", 0); +#endif + + if (FinalTime<=HallOfFame[selectedCircuit][k].bestTime) + { + +#if DEBUGXXX==1 + if (usb_is_open()) usb_fxlink_text("found", 0); +#endif + + for( int l=4; l>k; l--) + { + HallOfFame[selectedCircuit][l].playerName[0] = HallOfFame[selectedCircuit][l-1].playerName[0]; + HallOfFame[selectedCircuit][l].playerName[1] = HallOfFame[selectedCircuit][l-1].playerName[1]; + HallOfFame[selectedCircuit][l].playerName[2] = HallOfFame[selectedCircuit][l-1].playerName[2]; + HallOfFame[selectedCircuit][l].padding = HallOfFame[selectedCircuit][l-1].padding; + HallOfFame[selectedCircuit][l].bestScore = HallOfFame[selectedCircuit][l-1].bestScore; + HallOfFame[selectedCircuit][l].bestTime = HallOfFame[selectedCircuit][l-1].bestTime; + } + + HallOfFame[selectedCircuit][k].playerName[0] = PlayerName[0]; + HallOfFame[selectedCircuit][k].playerName[1] = PlayerName[1]; + HallOfFame[selectedCircuit][k].playerName[2] = PlayerName[2]; + HallOfFame[selectedCircuit][k].padding = 'X'; + HallOfFame[selectedCircuit][k].bestScore = score; + HallOfFame[selectedCircuit][k].bestTime = FinalTime; + + donerank = true; + skipranking = true; + + gint_world_switch( GINT_CALL( saveprogress ) ); + + } + else k++; + } + + } + } @@ -1175,7 +1291,7 @@ int main(void) // We set back zeros at the end of the program - if (canWeAllocateMore) memset( extended_ram.start, 0, 0x00300000 ); + memset(extended_ram.start, 0, (char *)extended_ram.end - (char *)extended_ram.start); return 1; diff --git a/src/src/circuit.cc b/src/src/circuit.cc index 708121a..805dbdf 100644 --- a/src/src/circuit.cc +++ b/src/src/circuit.cc @@ -20,7 +20,7 @@ #include -extern uint8_t NB_CARS_TRAFFIC; +extern uint16_t NB_CARS_TRAFFIC; extern std::vector circuit; extern std::vector nuages; diff --git a/src/src/menus.cc b/src/src/menus.cc index 33cf6d9..14ecd8a 100644 --- a/src/src/menus.cc +++ b/src/src/menus.cc @@ -8,8 +8,11 @@ #include #include "../include/utils.h" +#include "../include/saves.h" +extern BestRanking HallOfFame[10][5]; + extern uint8_t NB_CARS_TRAFFIC; @@ -33,6 +36,9 @@ int8_t CircuitSelection=0; bool doneMenuDetailsCircuit = false; int8_t CircuitDetailsSelection=0; +bool doneMenuBestTime = false; +int8_t BestTimeSelection=0; + bool doneMenuCredit = false; bool doneOptions = false; @@ -1156,3 +1162,108 @@ void getInputCircuitDetails( void ) } } + + + +int drawMenuBestTime( int circuit ) +{ + uint16_t pulse=0; + doneMenuBestTime = false; + + BestTimeSelection=0; + + + while (!doneMenuBestTime) + { + + dclear( C_BLACK ); + dsubimage( 0, 32, &mainscreen, 0, 32, 396, 160, DIMAGE_NONE); + + dfont(&autofont); + + dprint_opt(198, 2, C_RGB(pulse%256,0,pulse%256), C_NONE, DTEXT_CENTER, DTEXT_TOP, "HALL OF FAME" ); + + for( int k=0; k<5; k++) + { + if (HallOfFame[circuit][k].bestTime != 9999) + { + dprint_opt(12, 40+k*30, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "%d %c%c%c - %D sec", k+1, HallOfFame[circuit][k].playerName[0],HallOfFame[circuit][k].playerName[1],HallOfFame[circuit][k].playerName[2], HallOfFame[circuit][k].bestTime ); + dprint_opt(12, 38+k*30, C_RGB(255, 255, 255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "%d %c%c%c - %D sec", k+1, HallOfFame[circuit][k].playerName[0],HallOfFame[circuit][k].playerName[1],HallOfFame[circuit][k].playerName[2], HallOfFame[circuit][k].bestTime ); + } + else + { + dprint_opt(12, 40+k*30, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "%d %c%c%c - ... sec", k+1, HallOfFame[circuit][k].playerName[0],HallOfFame[circuit][k].playerName[1],HallOfFame[circuit][k].playerName[2], HallOfFame[circuit][k].bestTime ); + dprint_opt(12, 38+k*30, C_RGB(255, 255, 255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "%d %c%c%c - ... sec", k+1, HallOfFame[circuit][k].playerName[0],HallOfFame[circuit][k].playerName[1],HallOfFame[circuit][k].playerName[2], HallOfFame[circuit][k].bestTime ); + } + } + + dprint_opt(198, 222, C_RGB(pulse%256,0,pulse%256), C_NONE, DTEXT_CENTER, DTEXT_BOTTOM, ">> START <<" ); + + dupdate(); + + pulse++; + getInputBestTime(); + +#if IS_FXLIB==1 + if (screenshot && usb_is_open()) + { + usb_fxlink_screenshot(false); + screenshot = false; + } + + if(record && usb_is_open()) + { + usb_fxlink_videocapture(false); + } +#endif + + } + + return BestTimeSelection; +} + +void getInputBestTime( void ) +{ + int opt = GETKEY_DEFAULT & ~GETKEY_REP_ARROWS; + int timeout = 1; + + while(1) + { + key_event_t ev = getkey_opt(opt, &timeout); + if(ev.type == KEYEV_NONE) return; + + int key = ev.key; + + if (key==KEY_EXE) + { + doneMenuBestTime = true; + BestTimeSelection = 1; + } + + if (key==KEY_EXIT) + { + BestTimeSelection = -1; + doneMenuBestTime = true; + } + + +/* + if (key==KEY_UP || key==KEY_LEFT) + { + if (CircuitSelection==0) CircuitSelection=9; + else CircuitSelection--; + } + + if (key==KEY_DOWN || key==KEY_RIGHT) + { + if (CircuitSelection==9) CircuitSelection=0; + else CircuitSelection++; + } +*/ + +#if IS_FXLIB==1 + if(keydown(KEY_7)) screenshot = true; + if(keydown(KEY_8)) record = !record; +#endif // IS_FXLIB + } +} diff --git a/src/src/saves.cc b/src/src/saves.cc new file mode 100644 index 0000000..0d580ad --- /dev/null +++ b/src/src/saves.cc @@ -0,0 +1,51 @@ +#include "../include/saves.h" +#include +#include + + +static const char *filepath= "OutRun.sav"; +bool saveexist; +unsigned int sizeoffile; + + +extern BestRanking HallOfFame[10][5]; + + +void is_save_existing( void ) +{ + FILE *file = fopen( filepath, "r" ); + + if (file==NULL) + { + fclose( file ); + saveexist = false; + } + else + { + fclose( file ); + saveexist = true; + } +} + + +void saveprogress( void ) +{ + sizeoffile = sizeof( HallOfFame ); + + FILE *file = fopen( filepath, "w" ); + fwrite( HallOfFame, sizeoffile, 1, file ); + + fclose( file ); +} + + +void loadprogress( void ) +{ + sizeoffile = sizeof( HallOfFame ); + + FILE *file = fopen( filepath, "r" ); + fread( HallOfFame, sizeoffile, 1, file ); + + fclose( file ); +} +