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 );
+}
+