diff --git a/CMakeLists.txt b/CMakeLists.txt
index bec66d4..e75b7e7 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/utils.cc
)
set(ASSETS_cg
@@ -90,7 +91,7 @@ set(ASSETS_cg
assets-cg/fonts/auto20.png
assets-cg/fonts/startseq.png
assets-cg/fonts/plate5.png
-
+
assets-cg/menus/flag.png
assets-cg/menus/bigflag.png
diff --git a/CppOutRun.cbp b/CppOutRun.cbp
index 200dd18..ff6da79 100644
--- a/CppOutRun.cbp
+++ b/CppOutRun.cbp
@@ -38,6 +38,7 @@
+
@@ -47,6 +48,7 @@
+
diff --git a/CppOutRun.layout b/CppOutRun.layout
index a9737d0..868da63 100644
--- a/CppOutRun.layout
+++ b/CppOutRun.layout
@@ -2,109 +2,36 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
@@ -112,9 +39,27 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -122,9 +67,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fxlink-image-2022.02.26-23h13-4.png b/fxlink-image-2022.02.26-23h13-4.png
new file mode 100644
index 0000000..a933b91
Binary files /dev/null and b/fxlink-image-2022.02.26-23h13-4.png differ
diff --git a/fxlink-image-2022.02.26-23h14-2.png b/fxlink-image-2022.02.26-23h14-2.png
new file mode 100644
index 0000000..ec30c64
Binary files /dev/null and b/fxlink-image-2022.02.26-23h14-2.png differ
diff --git a/fxlink-image-2022.02.26-23h15-2.png b/fxlink-image-2022.02.26-23h15-2.png
new file mode 100644
index 0000000..178a89d
Binary files /dev/null and b/fxlink-image-2022.02.26-23h15-2.png differ
diff --git a/fxlink-image-2022.02.26-23h16-2.png b/fxlink-image-2022.02.26-23h16-2.png
new file mode 100644
index 0000000..16e19e8
Binary files /dev/null and b/fxlink-image-2022.02.26-23h16-2.png differ
diff --git a/fxlink-image-2022.02.26-23h17-5.png b/fxlink-image-2022.02.26-23h17-5.png
new file mode 100644
index 0000000..c495e52
Binary files /dev/null and b/fxlink-image-2022.02.26-23h17-5.png differ
diff --git a/fxlink-image-2022.02.26-23h24-1.png b/fxlink-image-2022.02.26-23h24-1.png
new file mode 100644
index 0000000..809f75f
Binary files /dev/null and b/fxlink-image-2022.02.26-23h24-1.png differ
diff --git a/fxlink-image-2022.02.26-23h24-2.png b/fxlink-image-2022.02.26-23h24-2.png
new file mode 100644
index 0000000..4c9960f
Binary files /dev/null and b/fxlink-image-2022.02.26-23h24-2.png differ
diff --git a/fxlink-image-2022.02.26-23h24-3.png b/fxlink-image-2022.02.26-23h24-3.png
new file mode 100644
index 0000000..c22cff3
Binary files /dev/null and b/fxlink-image-2022.02.26-23h24-3.png differ
diff --git a/fxlink-image-2022.02.26-23h25-1.png b/fxlink-image-2022.02.26-23h25-1.png
new file mode 100644
index 0000000..85d9b4d
Binary files /dev/null and b/fxlink-image-2022.02.26-23h25-1.png differ
diff --git a/src/include/cars.h b/src/include/cars.h
index 47e432d..b16c12e 100644
--- a/src/include/cars.h
+++ b/src/include/cars.h
@@ -25,6 +25,8 @@ class Cars
uint8_t Speed;
uint8_t Type;
+ int8_t Turn=0;
+
//uint8_t DScale;
// for debugging only
diff --git a/src/include/menus.h b/src/include/menus.h
index ed92351..2e34ca5 100644
--- a/src/include/menus.h
+++ b/src/include/menus.h
@@ -24,4 +24,7 @@ void drawPauseQuit( void );
void getInputPauseQuit( void );
+int drawMenuCircuitDetails( int circuit, int mode );
+void getInputCircuitDetails( void );
+
#endif // MENUS_H
diff --git a/src/include/utils.h b/src/include/utils.h
new file mode 100644
index 0000000..30f9a65
--- /dev/null
+++ b/src/include/utils.h
@@ -0,0 +1,20 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+
+#include
+#include
+#include
+
+
+size_t image_size_profile(int profile, int width, int height);
+
+size_t image_size(bopti_image_t const *img);
+
+int get_pixel(bopti_image_t const *img, int x, int y);
+
+void set_pixel(bopti_image_t *img, int x, int y, int color);
+
+bopti_image_t *resize(bopti_image_t const *src, int w, int h);
+
+#endif // UTILS_H
diff --git a/src/main.cc b/src/main.cc
index 0f45add..06518e2 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -57,6 +57,7 @@ struct DataPerf
DataPerf GraphPerf[ MAXDATA ];
unsigned int DataIndex=0;
+uint8_t NB_CARS_TRAFFIC=200;
bool stop = false;
bool exitToOS = false;
@@ -106,7 +107,6 @@ int CS=0;
-
void initEverything( void )
{
CurrentCircuitBiome = PLAINS;
@@ -371,7 +371,7 @@ int main(void)
int32_t start_time = 100000000;
uint32_t score=0;
uint8_t stage=0;
- int8_t selectedCircuit=0;
+ int8_t selectedCircuit=0, secondvalidation=0;
uint32_t time_update=0, time_create=0, time_project=0, time_render=0;
@@ -386,10 +386,19 @@ int main(void)
exitflag = false;
stage = drawMainMenu();
- if (stage==0 || stage==1)
+ if (stage==0)
{
selectedCircuit = drawMenuCircuitSelect();
- if (selectedCircuit != -1) exitflag=true;
+
+ if (selectedCircuit != -1) secondvalidation = drawMenuCircuitDetails( selectedCircuit, 0 );
+ if (selectedCircuit != -1 && secondvalidation != -1) exitflag=true;
+ }
+ else if (stage==1)
+ {
+ selectedCircuit = drawMenuCircuitSelect();
+
+ if (selectedCircuit != -1) secondvalidation = drawMenuCircuitDetails( selectedCircuit, 1 );
+ if (selectedCircuit != -1 && secondvalidation != -1) exitflag=true;
}
else if (stage==2)
{
@@ -562,8 +571,8 @@ int main(void)
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
+ 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
}
}
@@ -571,11 +580,97 @@ int main(void)
{
uint8_t indexCar = circuit[indexstart+1]->CarList[l];
- if (traffic[indexCar]->wX>(roadpart-0.20f) && traffic[indexCar]->wX<(roadpart+0.20f) && traffic[indexCar]->SpeedwX>(roadpart-0.22f) && traffic[indexCar]->wX<(roadpart+0.22f) && traffic[indexCar]->SpeedSpeed - 0.5;
}
}
+
+ if (DiffLevel>=1) // Normal or Hard : cars can overtake the other opponents
+ {
+
+ for( unsigned int k=indexstart; kCarList.size(); l++ ) // For all cars inside that road segment
+ {
+ uint8_t indexCar = circuit[k]->CarList[l];
+
+ for( unsigned int m=0; mCarList.size(); m++ )
+ {
+ uint8_t indexCar2 = circuit[k+1]->CarList[m];
+
+ if (traffic[indexCar]->wX==traffic[indexCar2]->wX && traffic[indexCar]->Speed>=traffic[indexCar2]->Speed) // a car is following and other one just in front of ehr, at the same speed or quicker
+ {
+ //if (traffic[indexCar]->wX>=-0.25) traffic[indexCar]->wX-=0.5;
+ //else traffic[indexCar]->wX=-0.25;
+
+ if (traffic[indexCar]->wX>=-0.25) traffic[indexCar]->Turn = -1;
+ else traffic[indexCar]->Turn = +1;
+ }
+ }
+ }
+ }
+
+ if (DiffLevel==2) // if difficulty set to hard, we allo changing lane (random based if not currently overtaking an other car)
+ {
+
+ for (unsigned int u=indexstart; uCarList.size(); v++)
+ {
+ unsigned int k = circuit[u]->CarList[v];
+
+ if (traffic[k]->Turn == 0)
+ {
+ int mov = rand() % 100;
+
+ if (mov>=95) // we let the car change its lane in 5% of cases
+ {
+ if (traffic[k]->wX==-0.75) traffic[k]->Turn = +1;
+ else if (traffic[k]->wX==0.75) traffic[k]->Turn = -1;
+ else
+ {
+ int side = -1 + (rand()%3);
+ traffic[k]->Turn = side;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ for (unsigned int u=indexstart; uCarList.size(); v++)
+ {
+
+ unsigned int k = circuit[u]->CarList[v];
+
+
+
+ /*
+ if (traffic[k]->Turn == -1)
+ {
+ traffic[k]->wX -= 0.10;
+ if (traffic[k]->wX==-0.75 || traffic[k]->wX==-0.25 || traffic[k]->wX==0.25) traffic[k]->Turn = 0;
+ }
+ else if (traffic[k]->Turn == 1)
+ {
+ traffic[k]->wX += 0.10;
+ if (traffic[k]->wX==-0.25 || traffic[k]->wX==0.25 || traffic[k]->wX==0.75) traffic[k]->Turn = 0;
+ }
+ */
+
+ traffic[k]->wX += (float) traffic[k]->Turn * 0.10f;
+ if (traffic[k]->wX>=-0.80 && traffic[k]->wX<=-0.70) traffic[k]->wX = -0.75, traffic[k]->Turn = 0;
+ else if (traffic[k]->wX>=-0.30 && traffic[k]->wX<=-0.20) traffic[k]->wX = -0.25, traffic[k]->Turn = 0;
+ else if (traffic[k]->wX>=0.20 && traffic[k]->wX<=0.30) traffic[k]->wX = 0.25, traffic[k]->Turn = 0;
+ else if (traffic[k]->wX>=0.70 && traffic[k]->wX<=0.80) traffic[k]->wX = 0.75, traffic[k]->Turn = 0;
+ }
+ }
+
+ }
}
uint16_t cumulCurve=0;
@@ -627,7 +722,7 @@ int main(void)
}
- cam->cY = fix( 300+2*CS ) + interpolatePositionY(fround(cam->cZ) );
+ cam->cY = fix( 350+2*CS ) + interpolatePositionY(fround(cam->cZ) );
for( int k=indexend-1; k>=indexstart; k--)
{
diff --git a/src/parameters.h b/src/parameters.h
index e964d3f..15f7634 100644
--- a/src/parameters.h
+++ b/src/parameters.h
@@ -19,7 +19,6 @@
#define NB_CLOUDS_SKY 10
-#define NB_CARS_TRAFFIC 200
#define MAX_SUBIMAGES_TREES 12
#define NB_TREES_TYPES 15
diff --git a/src/src/circuit.cc b/src/src/circuit.cc
index 9395263..a887631 100644
--- a/src/src/circuit.cc
+++ b/src/src/circuit.cc
@@ -12,7 +12,9 @@
#include "../include/drawstuff.h"
#include "../colors.h"
+#include "../include/utils.h"
+extern uint8_t NB_CARS_TRAFFIC;
extern std::vector circuit;
extern std::vector nuages;
@@ -43,105 +45,14 @@ bopti_image_t *scaledCars[NB_CARS_TYPES][MAX_SUBIMAGES_CARS] = { 0 };
extern int CurrentCircuitBiome;
-
-size_t image_size_profile(int profile, int width, int height)
-{
- size_t size = sizeof(bopti_image_t);
-
- if(profile == 0 || profile == 1) // PX_RGB565, PX_RGB565A
- size += width * height * 2;
- else if(profile == 2) // PX_P8
- size += 512 + width * height;
- else if(profile == 3) // PX_P4
- size += 32 + ((width + 1) / 2) * height;
-
- return size;
-}
-
-size_t image_size(bopti_image_t const *img)
-{
- return image_size_profile(img->profile, img->width, img->height);
-}
-
-int get_pixel(bopti_image_t const *img, int x, int y)
-{
- if((unsigned)x >= img->width || (unsigned)y >= img->height)
- return 0;
-
- uint8_t *bytes = (void *)img->data;
-
- if(img->profile <= 1)
- return img->data[y * img->width + x];
- if(img->profile == 2)
- return bytes[y * img->width + x + 512];
- if(img->profile == 3)
- {
- int s = (img->width + 1) >> 1;
- int i = y * s + (x >> 1) + 32;
- if(x & 1)
- return bytes[i] & 0x0f;
- else
- return bytes[i] >> 4;
- }
- return 0;
-}
-
-void set_pixel(bopti_image_t *img, int x, int y, int color)
-{
- if((unsigned)x >= img->width || (unsigned)y >= img->height)
- return;
-
- uint8_t *bytes = (void *)img->data;
-
- if(img->profile <= 1)
- img->data[y * img->width + x] = color;
- else if(img->profile == 2)
- bytes[y * img->width + x + 512] = color;
- else if(img->profile == 3)
- {
- int s = (img->width + 1) >> 1;
- int i = y * s + (x >> 1) + 32;
- if(x & 1)
- bytes[i] = (bytes[i] & 0xf0) | (color & 0x0f);
- else
- bytes[i] = (bytes[i] & 0x0f) | ((color & 0x0f) << 4);
- }
-}
-
-bopti_image_t *resize(bopti_image_t const *src, int w, int h)
-{
- size_t size = image_size_profile(src->profile, w, h);
- bopti_image_t *img = malloc(size);
- if(!img) return NULL;
-
- size_t palette_size = 0;
- if(src->profile == 2) // PX_P8
- palette_size = 512;
- else if(src->profile == 3) // PX_P4
- palette_size = 32;
-
- img->profile = src->profile;
- img->alpha = src->alpha;
- img->width = w;
- img->height = h;
- memcpy(img->data, src->data, palette_size);
-
- for(int y = 0; y < h; y++)
- for(int x = 0; x < w; x++)
- {
- int color = get_pixel(src, x * src->width / w, y * src->height / h);
- set_pixel(img, x, y, color);
- }
-
- return img;
-}
+extern int DiffLevel;
void initData( void )
{
cam = new camera();
cam->cX = fixdouble(0.0f);
- cam->cY = fixdouble(300.0f);
+ cam->cY = fixdouble(350.0f);
cam->cZ = fixdouble(100.0f);
}
@@ -609,7 +520,14 @@ void createTraffic( uint16_t maxSegment )
double Z = (double) (SEGMENT_LENGTH * (rand() % (maxSegment-5)) + 10.0);
//int8_t X = 0;
//double Z = (k+1)*SEGMENT_LENGTH;
- uint8_t S = 2 + (rand() % 3);
+
+ uint8_t S;
+
+ // if Difficulty = easy, all cars are at the same speed 175km/h)
+ if (DiffLevel==0) S=3.5;
+ else S = 2 + (rand() % 3); // else speed is random and then overtaking can happen
+
+
uint8_t T = rand() % 8;
Cars* car;
diff --git a/src/src/menus.cc b/src/src/menus.cc
index 2dca4ca..aa95720 100644
--- a/src/src/menus.cc
+++ b/src/src/menus.cc
@@ -5,6 +5,12 @@
#include
#include
+#include
+
+#include "../include/utils.h"
+
+
+extern uint8_t NB_CARS_TRAFFIC;
extern bopti_image_t mainscreen;
@@ -24,6 +30,9 @@ uint8_t MainMenuSelection=0;
bool doneMenuCircuit = false;
int8_t CircuitSelection=0;
+bool doneMenuDetailsCircuit = false;
+int8_t CircuitDetailsSelection=0;
+
bool doneMenuCredit = false;
bool doneOptions = false;
@@ -106,8 +115,8 @@ void getInputStartTitle( void )
doneTitle = true;
#if IS_FXLIB==1
- if(keydown(KEY_F5)) screenshot = true;
- if(keydown(KEY_F6)) record = !record;
+ if(keydown(KEY_7)) screenshot = true;
+ if(keydown(KEY_8)) record = !record;
#endif // IS_FXLIB
}
@@ -208,8 +217,8 @@ void getInputMainMenu( void )
else MainMenuSelection++;
}
#if IS_FXLIB==1
- if(keydown(KEY_F5)) screenshot = true;
- if(keydown(KEY_F6)) record = !record;
+ if(keydown(KEY_7)) screenshot = true;
+ if(keydown(KEY_8)) record = !record;
#endif // IS_FXLIB
}
}
@@ -398,8 +407,8 @@ void getInputCircuitSelect( void )
}
#if IS_FXLIB==1
- if(keydown(KEY_F5)) screenshot = true;
- if(keydown(KEY_F6)) record = !record;
+ if(keydown(KEY_7)) screenshot = true;
+ if(keydown(KEY_8)) record = !record;
#endif // IS_FXLIB
}
}
@@ -495,8 +504,8 @@ void getInputCredit( void )
doneMenuCredit = true;
#if IS_FXLIB==1
- if(keydown(KEY_F5)) screenshot = true;
- if(keydown(KEY_F6)) record = !record;
+ if(keydown(KEY_7)) screenshot = true;
+ if(keydown(KEY_8)) record = !record;
#endif // IS_FXLIB
}
}
@@ -651,8 +660,8 @@ void getInputOptions( void )
}
#if IS_FXLIB==1
- if(keydown(KEY_F5)) screenshot = true;
- if(keydown(KEY_F6)) record = !record;
+ if(keydown(KEY_7)) screenshot = true;
+ if(keydown(KEY_8)) record = !record;
#endif // IS_FXLIB
}
}
@@ -767,6 +776,13 @@ void drawGameOptions( void )
#endif
}
+
+ if (CarsNumb==0) NB_CARS_TRAFFIC=50;
+ else if (CarsNumb==1) NB_CARS_TRAFFIC=100;
+ else if (CarsNumb==2) NB_CARS_TRAFFIC=200;
+ else NB_CARS_TRAFFIC=150;
+
+
SkipTime = true; // To avoid counting or de-counting time during menu
return;
@@ -854,8 +870,8 @@ void getInputGameOptions( void )
}
#if IS_FXLIB==1
- if(keydown(KEY_F5)) screenshot = true;
- if(keydown(KEY_F6)) record = !record;
+ if(keydown(KEY_7)) screenshot = true;
+ if(keydown(KEY_8)) record = !record;
#endif // IS_FXLIB
}
}
@@ -969,8 +985,175 @@ void getInputPauseQuit( void )
}
#if IS_FXLIB==1
- if(keydown(KEY_F5)) screenshot = true;
- if(keydown(KEY_F6)) record = !record;
+ if(keydown(KEY_7)) screenshot = true;
+ if(keydown(KEY_8)) record = !record;
#endif // IS_FXLIB
}
}
+
+
+
+int drawMenuCircuitDetails( int circuit, int mode )
+{
+ uint16_t pulse=0;
+ doneMenuDetailsCircuit = false;
+
+ CircuitDetailsSelection=0;
+
+ bopti_image_t *preview1=nullptr, *preview2=nullptr, *src1=nullptr, *src2=nullptr;
+
+ if (circuit==0) src1=&plains1, src2=&linear;
+ else if (circuit==1) src1=&desert1, src2=&linear;
+ else if (circuit==2) src1=&usa1, src2=&linear;
+ else if (circuit==3) src1=&finland1, src2=&linear;
+ else if (circuit==4) src1=&usa1, src2=&linear;
+ else if (circuit==5) src1=&plains1, src2=&circular;
+ else if (circuit==6) src1=&desert1, src2=&circular;
+ else if (circuit==7) src1=&usa1, src2=&circular;
+ else if (circuit==8) src1=&finland1, src2=&circular;
+ else if (circuit==9) src1=&usa1, src2=&circular;
+
+ preview1 = resize( src1, src1->width*1.5, src1->height*1.5 );
+ preview2 = resize( src2, src2->width*1.5, src2->height*1.5 );
+
+
+ while (!doneMenuDetailsCircuit)
+ {
+
+ dclear( C_BLACK );
+ dsubimage( 0, 32, &mainscreen, 0, 32, 396, 140, DIMAGE_NONE);
+
+ dfont(&autofont);
+
+ dimage( 16, 45, preview1 );
+ dimage( 16, 45, preview2 );
+
+ drawRectangle( 16, 45, 90, 90, C_RGB(255,255,255), 3 );
+
+ if (circuit==0 || circuit==5) dprint_opt(198, 2, C_RGB(255,255,255), C_NONE, DTEXT_CENTER, DTEXT_TOP, "EUROPEAN PLAINS" );
+ else if (circuit==1 || circuit==6) dprint_opt(198, 2, C_RGB(255,255,255), C_NONE, DTEXT_CENTER, DTEXT_TOP, "ATACAMA DESERT" );
+ else if (circuit==2 || circuit==7) dprint_opt(198, 2, C_RGB(255,255,255), C_NONE, DTEXT_CENTER, DTEXT_TOP, "US ROAD 66" );
+ else if (circuit==3 || circuit==8) dprint_opt(198, 2, C_RGB(255,255,255), C_NONE, DTEXT_CENTER, DTEXT_TOP, "SNOW IN FINLAND" );
+ else if (circuit==4 || circuit==9) dprint_opt(198, 2, C_RGB(255,255,255), C_NONE, DTEXT_CENTER, DTEXT_TOP, "KENYAN SAVANAH" );
+
+
+ if (circuit==0 || circuit==1 || circuit==2 || circuit==5 || circuit==6 || circuit==7)
+ {
+ dprint_opt(122, 42, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "GRIP - GOOD" );
+ dprint_opt(120, 40, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "GRIP - GOOD" );
+ }
+ else if (circuit==3 || circuit==8)
+ {
+ dprint_opt(122, 42, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "GRIP - LOW" );
+ dprint_opt(120, 40, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "GRIP - LOW" );
+ }
+ else if (circuit==4 || circuit==9)
+ {
+ dprint_opt(122, 42, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "GRIP - SLIDE" );
+ dprint_opt(120, 40, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "GRIP - SLIDE" );
+ }
+
+
+ if (circuit==0 || circuit==1 || circuit==2 || circuit==5 || circuit==6 || circuit==7)
+ {
+ dprint_opt(122, 82, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "ASPHALT" );
+ dprint_opt(120, 80, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "ASPHALT" );
+ }
+ else if (circuit==3 || circuit==8)
+ {
+ dprint_opt(122, 82, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "ICE AND SNOW" );
+ dprint_opt(120, 80, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "ICE AND SNOW" );
+ }
+ else if (circuit==4 || circuit==9)
+ {
+ dprint_opt(122, 82, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "DIRT AND DUST" );
+ dprint_opt(120, 80, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "DIRT AND DUST" );
+ }
+
+
+ if (circuit==0 || circuit==1 || circuit==2 || circuit==3 || circuit==4)
+ {
+ dprint_opt(122, 122, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "ONE LAP" );
+ dprint_opt(120, 120, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "ONE LAP" );
+ }
+ else
+ {
+ dprint_opt(122, 122, C_RGB(0,0,0), C_NONE, DTEXT_LEFT, DTEXT_TOP, "THREE LAPS" );
+ dprint_opt(120, 120, C_RGB(255,255,255), C_NONE, DTEXT_LEFT, DTEXT_TOP, "THREE LAPS" );
+ }
+
+ dprint_opt(198, 197, C_RGB(pulse%256,0,pulse%256), C_NONE, DTEXT_CENTER, DTEXT_BOTTOM, ">> HANG ON TO <<" );
+ dprint_opt(198, 222, C_RGB(pulse%256,0,pulse%256), C_NONE, DTEXT_CENTER, DTEXT_BOTTOM, ">> YOUR HELMET <<" );
+
+ dupdate();
+
+ pulse++;
+ getInputCircuitDetails();
+
+#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
+
+ }
+
+ free(preview1);
+ free(preview2);
+
+ return CircuitDetailsSelection;
+}
+
+void getInputCircuitDetails( 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)
+ {
+ doneMenuDetailsCircuit = true;
+ CircuitDetailsSelection = 1;
+ }
+
+ if (key==KEY_EXIT)
+ {
+ CircuitDetailsSelection = -1;
+ doneMenuDetailsCircuit = 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/utils.cc b/src/src/utils.cc
new file mode 100644
index 0000000..edeb33e
--- /dev/null
+++ b/src/src/utils.cc
@@ -0,0 +1,96 @@
+#include "../include/utils.h"
+
+
+
+size_t image_size_profile(int profile, int width, int height)
+{
+ size_t size = sizeof(bopti_image_t);
+
+ if(profile == 0 || profile == 1) // PX_RGB565, PX_RGB565A
+ size += width * height * 2;
+ else if(profile == 2) // PX_P8
+ size += 512 + width * height;
+ else if(profile == 3) // PX_P4
+ size += 32 + ((width + 1) / 2) * height;
+
+ return size;
+}
+
+size_t image_size(bopti_image_t const *img)
+{
+ return image_size_profile(img->profile, img->width, img->height);
+}
+
+int get_pixel(bopti_image_t const *img, int x, int y)
+{
+ if((unsigned)x >= img->width || (unsigned)y >= img->height)
+ return 0;
+
+ uint8_t *bytes = (void *)img->data;
+
+ if(img->profile <= 1)
+ return img->data[y * img->width + x];
+ if(img->profile == 2)
+ return bytes[y * img->width + x + 512];
+ if(img->profile == 3)
+ {
+ int s = (img->width + 1) >> 1;
+ int i = y * s + (x >> 1) + 32;
+ if(x & 1)
+ return bytes[i] & 0x0f;
+ else
+ return bytes[i] >> 4;
+ }
+ return 0;
+}
+
+void set_pixel(bopti_image_t *img, int x, int y, int color)
+{
+ if((unsigned)x >= img->width || (unsigned)y >= img->height)
+ return;
+
+ uint8_t *bytes = (void *)img->data;
+
+ if(img->profile <= 1)
+ img->data[y * img->width + x] = color;
+ else if(img->profile == 2)
+ bytes[y * img->width + x + 512] = color;
+ else if(img->profile == 3)
+ {
+ int s = (img->width + 1) >> 1;
+ int i = y * s + (x >> 1) + 32;
+ if(x & 1)
+ bytes[i] = (bytes[i] & 0xf0) | (color & 0x0f);
+ else
+ bytes[i] = (bytes[i] & 0x0f) | ((color & 0x0f) << 4);
+ }
+}
+
+bopti_image_t *resize(bopti_image_t const *src, int w, int h)
+{
+ size_t size = image_size_profile(src->profile, w, h);
+ bopti_image_t *img = malloc(size);
+ if(!img) return NULL;
+
+ size_t palette_size = 0;
+ if(src->profile == 2) // PX_P8
+ palette_size = 512;
+ else if(src->profile == 3) // PX_P4
+ palette_size = 32;
+
+ img->profile = src->profile;
+ img->alpha = src->alpha;
+ img->width = w;
+ img->height = h;
+ memcpy(img->data, src->data, palette_size);
+
+ for(int y = 0; y < h; y++)
+ for(int x = 0; x < w; x++)
+ {
+ int color = get_pixel(src, x * src->width / w, y * src->height / h);
+ set_pixel(img, x, y, color);
+ }
+
+ return img;
+}
+