From ddc326403ff4f9d1d694d67c2bfc2eae32c18b69 Mon Sep 17 00:00:00 2001 From: Slyvtt Date: Sun, 6 Mar 2022 20:21:22 +0100 Subject: [PATCH] added curves/hills --- CMakeLists.txt | 22 ++-- CppOutRun.layout | 76 ++++++++------ assets-cg/player/fxconv-metadata.txt | 5 + assets-cg/player/player.png | Bin 0 -> 4430 bytes assets-cg/trees/fxconv-metadata.txt | 5 + assets-cg/trees/tree1.png | Bin 0 -> 12220 bytes assets-cg/trees/tree2.png | Bin 0 -> 13872 bytes assets-cg/trees/tree3.png | Bin 0 -> 22745 bytes src/fixed.h | 5 +- src/include/circuit.h | 45 ++++++++ src/include/drawstuff.h | 4 +- src/include/segment.h | 24 +++-- src/main.cc | 109 +++++++++++++++----- src/parameters.h | 4 +- src/src/circuit.cc | 149 +++++++++++++++++++++++---- src/src/drawstuff.cc | 22 +--- src/src/segment.cc | 39 +++++-- 17 files changed, 380 insertions(+), 129 deletions(-) create mode 100644 assets-cg/player/fxconv-metadata.txt create mode 100644 assets-cg/player/player.png create mode 100644 assets-cg/trees/fxconv-metadata.txt create mode 100644 assets-cg/trees/tree1.png create mode 100644 assets-cg/trees/tree2.png create mode 100644 assets-cg/trees/tree3.png diff --git a/CMakeLists.txt b/CMakeLists.txt index bf91817..c4a6318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,14 +19,18 @@ set(SOURCES ) set(ASSETS_cg -# assets-cg/traffic/car1.png -# assets-cg/traffic/car2.png -# assets-cg/traffic/car3.png -# assets-cg/traffic/car4.png -# assets-cg/traffic/car5.png -# assets-cg/traffic/car6.png -# assets-cg/traffic/car7.png -# assets-cg/traffic/car8.png + assets-cg/traffic/car1.png + assets-cg/traffic/car2.png + assets-cg/traffic/car3.png + assets-cg/traffic/car4.png + assets-cg/traffic/car5.png + assets-cg/traffic/car6.png + assets-cg/traffic/car7.png + assets-cg/traffic/car8.png + assets-cg/trees/tree1.png + assets-cg/trees/tree2.png + assets-cg/trees/tree3.png + assets-cg/player/player.png ) fxconv_declare_assets(${ASSETS_cg} WITH_METADATA) @@ -37,6 +41,6 @@ target_link_libraries(myaddin LibProf::LibProf Gint::Gint -lustl -lc) target_link_options(myaddin PRIVATE -Wl,-Map=Build_Addin.map) if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50) - generate_g3a(TARGET myaddin OUTPUT "OutRunFP.g3a" VERSION 00.100.0000 + generate_g3a(TARGET myaddin OUTPUT "OutRunFP.g3a" VERSION 00.150.0000 NAME "OutRunFP" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png) endif() diff --git a/CppOutRun.layout b/CppOutRun.layout index 03b2e38..c7a55ba 100644 --- a/CppOutRun.layout +++ b/CppOutRun.layout @@ -2,44 +2,14 @@ - + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + @@ -47,4 +17,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets-cg/player/fxconv-metadata.txt b/assets-cg/player/fxconv-metadata.txt new file mode 100644 index 0000000..7e05b58 --- /dev/null +++ b/assets-cg/player/fxconv-metadata.txt @@ -0,0 +1,5 @@ +*.png: + type: bopti-image + profile: p4 + name_regex: (.*)\.png \1 + diff --git a/assets-cg/player/player.png b/assets-cg/player/player.png new file mode 100644 index 0000000000000000000000000000000000000000..a6690fbfea646586e939443e71d6464c5909ae54 GIT binary patch literal 4430 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 literal 0 HcmV?d00001 diff --git a/assets-cg/trees/fxconv-metadata.txt b/assets-cg/trees/fxconv-metadata.txt new file mode 100644 index 0000000..7e05b58 --- /dev/null +++ b/assets-cg/trees/fxconv-metadata.txt @@ -0,0 +1,5 @@ +*.png: + type: bopti-image + profile: p4 + name_regex: (.*)\.png \1 + diff --git a/assets-cg/trees/tree1.png b/assets-cg/trees/tree1.png new file mode 100644 index 0000000000000000000000000000000000000000..0d094646e8334aa6544306ecdfa96ec4932791ad GIT binary patch literal 12220 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 KMNUMnLSTYdVD4W4 literal 0 HcmV?d00001 diff --git a/assets-cg/trees/tree2.png b/assets-cg/trees/tree2.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c50af98a57cfe4fb757ac4b21b649473702e21 GIT binary patch literal 13872 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 literal 0 HcmV?d00001 diff --git a/src/fixed.h b/src/fixed.h index 3568d11..e4b00e3 100644 --- a/src/fixed.h +++ b/src/fixed.h @@ -3,9 +3,8 @@ //--- #pragma once #include -typedef int64_t fixed_t; -//extended from initial int32_t +typedef int64_t fixed_t; /* Standard arithmetic. */ static inline fixed_t fmul(fixed_t left, fixed_t right) @@ -24,7 +23,7 @@ static inline fixed_t fdiv(fixed_t left, fixed_t right) #define fix(x) ((int)((x) * 65536)) -static inline fixed_t fixdouble(long double constant) +static inline fixed_t fixdouble(double constant) { return (fixed_t)(constant * 65536); } diff --git a/src/include/circuit.h b/src/include/circuit.h index 6816b7f..7e3938a 100644 --- a/src/include/circuit.h +++ b/src/include/circuit.h @@ -1,4 +1,41 @@ #include +#include "../fixed.h" + +enum Length +{ + L_VERYSHORT = 50, + L_SHORT = 100, + L_MEDIUM = 200, + L_LONG = 400, + L_VERYLONG = 1000 +}; + +enum HillSize +{ + H_SMALL = 10, + H_MEDIUM = 20, + H_BIG = 40 +}; + +enum HillType +{ + UP_HILL = +1, + DOWN_HILL = -1 +}; + +enum CurveStrength +{ + C_EASY = 2, + C_MEDIUM = 4, + C_HARD = 6 +}; + +enum CurveType +{ + LEFT_CURVE = -1, + RIGHT_CURVE = +1 +}; + void initData( void ); void createCircuit( void ); @@ -10,3 +47,11 @@ void printCircuit( void ); void printCircuit( int i ); void drawCircuitSegment( uint16_t index ); + +void addStraightLine( Length l ); +void addCurve( Length l, CurveStrength s, CurveType t ); +void addHill( Length l, HillSize s, HillType t ); + +fixed_t interpolatePositionX( double currentZ ); +fixed_t interpolatePositionY( double currentZ ); + diff --git a/src/include/drawstuff.h b/src/include/drawstuff.h index 5bb4992..fabdac5 100644 --- a/src/include/drawstuff.h +++ b/src/include/drawstuff.h @@ -2,8 +2,8 @@ #include void gint_dhline(int x1, int x2, int y, uint16_t color); -void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B, uint8_t A ); -void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B, uint8_t A ); +void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B ); +void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B ); void drawSky( void ); void drawSky( int ymin, int ymax ); diff --git a/src/include/segment.h b/src/include/segment.h index c6e507a..501445a 100644 --- a/src/include/segment.h +++ b/src/include/segment.h @@ -10,17 +10,29 @@ class Segment public: Segment(); Segment( uint16_t n_seg ); + Segment( int16_t x, int16_t y, double z, int8_t c ); + Segment( int16_t x, int16_t y, double z, int8_t c, int8_t left, int8_t right ); ~Segment(); void Project3DFP( camera* c ); - uint16_t Index=0; - uint8_t Curve=0; - fixed_t wX=0, wY=0, wZ=0; - fixed_t sX=0, sY=0, sW=0; - fixed_t Scale=0; - int X=0,Y=0,W=0; + int8_t Curve=0; + int16_t CumulatedCurve=0; + + // World Coordinates (X,Y,Z) + int16_t wX=0; + int16_t wY=0; + double wZ=0.0; + + // Screen Coordinates (X, Y) + width of the projected Road + int16_t X=0; + int16_t Y=0; + int16_t W=0; + + // Decorations on the Road (Left and Right) + int8_t Ldeco=0; + int8_t RDeco=0; }; #endif // SEGMENT_H diff --git a/src/main.cc b/src/main.cc index 52d81c9..127f6b6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -23,16 +23,22 @@ -//extern bopti_image_t car1, car2, car3, car4, car5, car6, car7, car8; +extern bopti_image_t car1, car2, car3, car4, car5, car6, car7, car8; +extern bopti_image_t tree1, tree2, tree3; +extern bopti_image_t player; std::vector circuit; +int MAX_SEGMENT=0; camera *cam; + bool stop = false; bool record = false; bool screenshot = false; +bool ShowDebug1 = false; +bool ShowDebug2 = false; uint16_t currentcurve=0; uint8_t shiftcolor=0; @@ -101,6 +107,17 @@ static void get_inputs( float dt ) if(keydown(KEY_EXIT)) stop = true; + if(keydown(KEY_F1)) + { + ShowDebug1 = !ShowDebug1; + ShowDebug2 = false; + } + if(keydown(KEY_F2)) + { + ShowDebug2 = !ShowDebug2; + ShowDebug1 = false; + } + if(keydown(KEY_F6)) record = !record; if(keydown(KEY_F4)) screenshot = true; @@ -146,8 +163,11 @@ int main(void) time_create = prof_time(perf_create); //-------------- + MAX_SEGMENT = circuit.size(); int indexstart = 0; + int indexend = 0; + uint32_t maxDistance = (MAX_SEGMENT-nbInterestingSegments-5)*SEGMENT_LENGTH; uint32_t dt=0; @@ -162,12 +182,14 @@ int main(void) if (fround(cam->cZ)<=0) cam->cZ=fixdouble(0.0); if (fround(cam->cZ)>=maxDistance) cam->cZ=fixdouble(maxDistance); - indexstart = (fround(cam->cZ) - 400) / SEGMENT_LENGTH; + indexstart = fround(cam->cZ) / SEGMENT_LENGTH; + indexend = indexstart+nbInterestingSegments+1; + // there is an offset equals to 400 on z position // this is to compute the first index of segment to be projected to screen if (indexstart<0) indexstart=0; - if (indexstart>MAX_SEGMENT-nbInterestingSegments-5-1) indexstart=MAX_SEGMENT-nbInterestingSegments-5-1; + if (indexstart>MAX_SEGMENT-nbInterestingSegments-1-2) indexstart=MAX_SEGMENT-nbInterestingSegments-1-2; //-------------- @@ -175,8 +197,15 @@ int main(void) perf_project = prof_make(); prof_enter(perf_project); - for (int k=indexstart; kcY = fix( 300 + interpolatePositionY(fround(cam->cZ)) ); + uint16_t cumulCurve=0; + for (int k=indexstart; k<=indexend; k++) // Need to project 1 more segment than actual drawing + { + projectCircuitFP( k ); + circuit[k]->CumulatedCurve = cumulCurve; + cumulCurve += circuit[k]->Curve; + } + prof_leave(perf_project); time_project = prof_time(perf_project); @@ -186,35 +215,61 @@ int main(void) perf_render = prof_make(); prof_enter(perf_render); - drawSky( ); + drawSky( ); - for (int k=indexstart; kcX = interpolatePositionX(fround(cam->cZ)); + cam->cY = fix( 300 ) + interpolatePositionY(fround(cam->cZ)); - //r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT); + //currentcurve = 0; - dprint( 1, 1, C_RED, "Circuit Creation = %.3D ms", time_create ); - dprint( 1, 15, C_RED, "Segments Projection = %.3D ms", time_project ); - dprint( 1, 29, C_RED, "Rendering = %.3D ms", time_render ); + //for (int k=indexstart; k=indexstart; k--) + { + currentcurve = circuit[k]->CumulatedCurve; + drawCircuitSegment( k ); + //currentcurve += circuit[k]->Curve; + } - dprint( 1, 55, C_WHITE, "Iteration = %d", l); - dprint( 1, 69, C_GREEN, "Indexstart = %d ", indexstart ); - dprint( 1, 83, C_GREEN, "Indexend = %d", indexstart+nbInterestingSegments+1 ); - dprint( 1, 97, C_RED, "Circuit Size = %d", circuit.size() ); + //r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT); + if (ShowDebug1) + { + Segment* currentSeg = circuit[indexstart]; - dprint( 300, 1, C_WHITE, "CamX= %d", fround( cam->cX ) ); - dprint( 300, 15, C_WHITE, "CamY= %d", fround( cam->cY ) ); - dprint( 300, 29, C_WHITE, "CamZ= %d", fround( cam->cZ ) ); + dprint( 1, 1, C_RED, "Cra=%.3D ms", time_create ); + dprint( 1, 15, C_RED, "Prj=%.3D ms", time_project ); + dprint( 1, 29, C_RED, "Rdr=%.3D ms", time_render ); - dprint( 280, 55, C_WHITE, "Dir = %d", direction ); - dprint( 280, 69, C_WHITE, "Spd = %.1f", speed ); - dprint( 280, 83, C_WHITE, "Dz = %.1f", speed*dt ); - dprint( 280, 97, C_WHITE, "dt = %.3D ms", dt ); + dprint( 1, 55, C_WHITE, "It=%d", l); + dprint( 1, 69, C_GREEN, "St=%d ", indexstart ); + dprint( 1, 83, C_GREEN, "En=%d", indexend ); + dprint( 1, 97, C_RED, "Sz= %d", circuit.size() ); + + dprint( 100, 55, C_WHITE, "SzSgmt=%d bytes", sizeof(Segment) ); + dprint( 100, 69, C_WHITE, ">XYZc=(%d,%d,%.0lf,%d)", circuit[indexstart]->wX, circuit[indexstart]->wY, circuit[indexstart]->wZ, circuit[indexstart]->Curve ); + dprint( 100, 83, C_WHITE, ">XYZc=(%d,%d,%.0lf,%d)", circuit[indexend]->wX, circuit[indexend]->wY, circuit[indexend]->wZ, circuit[indexstart]->Curve ); + dprint( 100, 97, C_WHITE, "C[i]Adr= %p", ¤tSeg), + + dprint( 320, 1, C_WHITE, "CamX=%d", fround( cam->cX ) ); + dprint( 320, 15, C_WHITE, "CamY=%d", fround( cam->cY ) ); + dprint( 320, 29, C_WHITE, "CamZ=%d", fround( cam->cZ ) ); + + dprint( 320, 55, C_WHITE, "Dir=%d", direction ); + dprint( 320, 69, C_WHITE, "Spd=%.1f", speed ); + dprint( 320, 83, C_WHITE, "Dz =%.1f", speed*dt ); + dprint( 320, 97, C_WHITE, "dt =%.3D ms", dt ); + } + if (ShowDebug2) + { + dprint( 1, 1, C_RED, "Cra=%.3D ms", time_create ); + dprint( 1, 15, C_RED, "Prj=%.3D ms", time_project ); + dprint( 1, 29, C_RED, "Rdr=%.3D ms", time_render ); + } + + dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-48, &player, 257,1,72,46, DIMAGE_NONE); + + //dupdate(); + r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT); - //r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT); - dupdate(); prof_leave(perf_render); time_render = prof_time(perf_render); diff --git a/src/parameters.h b/src/parameters.h index 8f1f6f4..e4717c1 100644 --- a/src/parameters.h +++ b/src/parameters.h @@ -14,9 +14,7 @@ #define ASPECT_RATIO 1.767 #define DISTANCE_SCREEN 0.83444 -#define MAX_RENDER_DISTANCE 1500 - -#define MAX_SEGMENT 10000 +#define MAX_RENDER_DISTANCE 2500 #define std ustl diff --git a/src/src/circuit.cc b/src/src/circuit.cc index dbf5eab..8849840 100644 --- a/src/src/circuit.cc +++ b/src/src/circuit.cc @@ -11,7 +11,8 @@ extern std::vector circuit; extern camera *cam; extern uint16_t currentcurve; extern uint8_t shiftcolor; - +extern int MAX_SEGMENT; +extern bool ShowDebug1; void initData( void ) { @@ -24,14 +25,81 @@ void initData( void ) void createCircuit( void ) { - for( int i=0; iwY; + lastZ=circuit[circuit.size()-1]->wZ; + } + + for( int i=0; iwY; + lastZ=circuit[circuit.size()-1]->wZ; + } + + for( int i=0; iwY; + lastZ=circuit[circuit.size()-1]->wZ; + } + + for( int i=0; iX, circuit[i]->Y, circuit[i]->W ); - //dprint(1, 1+10*(i), C_GREEN, "%d-(_sY,Y,W)=(%.0f,%.0f,%.0f)", i, circuit[i]->_sX, circuit[i]->_sY, circuit[i]->_sW ); + //dprint(1, 1+10*(i), C_GREEN, "%d-(_sY,Y,W)=(%.0f,%.0f,%.0f)", i, circuit[i]->_wX, circuit[i]->_wY, circuit[i]->_sW ); } }; @@ -78,40 +146,85 @@ void drawCircuitSegment( uint16_t index ) if (index%2==0) { - drawGrass( Y2, Y1, 0, 255-shiftcolor, 45-shiftcolor, 255 ); + drawGrass( Y2, Y1, 0, 255-shiftcolor, 45-shiftcolor ); // route - drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 196-shiftcolor, 196-shiftcolor, 196-shiftcolor, 255 ); + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 196-shiftcolor, 196-shiftcolor, 196-shiftcolor ); // ligne blanche centrale - drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor, 255 ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); // ligne blanche gauche - drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor, 255 ); + drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); // ligne blanche centrale gauche - drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor, 255 ); + drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); // ligne blanche centrale - drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor, 255 ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); // ligne blanche centrale droite - drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor, 255 ); + drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); // ligne blanche droite - drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor, 255 ); + drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); } else { - drawGrass( Y2, Y1, 0, 255-shiftcolor, 0, 255 ); + drawGrass( Y2, Y1, 0, 255-shiftcolor, 0 ); - drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 180-shiftcolor, 180-shiftcolor, 180-shiftcolor, 255 ); + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 180-shiftcolor, 180-shiftcolor, 180-shiftcolor ); // ligne rouge gauche - drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 0, 0, 255 ); + drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 0, 0 ); // ligne rouge droite - drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 0, 0, 255 ); + drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 0, 0 ); } - currentcurve += circuit[index]->Curve; +} + + +fixed_t interpolatePositionX( double currentZ ) +{ + int index = (int) (currentZ / SEGMENT_LENGTH); + fixed_t x1 = fix(circuit[index]->wX); + fixed_t x2 = fix(circuit[index+1]->wX); + fixed_t dZ = fixdouble(currentZ-index*SEGMENT_LENGTH); + + fixed_t result = x1 + fmul( x2-x1, fdiv( dZ, fix(SEGMENT_LENGTH))); + + if(ShowDebug1) + { + dprint( 120, 1, C_WHITE, "CZ=%.0lf", f2double(currentZ) ); + dprint( 120, 15, C_WHITE, "y1=%d", fround(x1) ); + dprint( 120, 29, C_WHITE, "y2=%d", fround(x2) ); + + dprint( 240, 15, C_WHITE, "Dz=%d", fround(dZ) ); + dprint( 240, 29, C_GREEN, "CX=%d", fround(result) ); + } + + return result; +} + + +fixed_t interpolatePositionY( double currentZ ) +{ + int index = (int) (currentZ / SEGMENT_LENGTH); + fixed_t y1 = fix(circuit[index]->wY); + fixed_t y2 = fix(circuit[index+1]->wY); + fixed_t dZ = fixdouble(currentZ-index*SEGMENT_LENGTH); + + fixed_t result = y1 + fmul( y2-y1, fdiv( dZ, fix(SEGMENT_LENGTH))); + + if(ShowDebug1) + { + dprint( 120, 1, C_WHITE, "CZ=%.0lf", f2double(currentZ) ); + dprint( 120, 15, C_WHITE, "y1=%d", fround(y1) ); + dprint( 120, 29, C_WHITE, "y2=%d", fround(y2) ); + + dprint( 240, 15, C_WHITE, "Dz=%d", fround(dZ) ); + dprint( 240, 43, C_GREEN, "CY=%d", fround(result) ); + } + + return result; } diff --git a/src/src/drawstuff.cc b/src/src/drawstuff.cc index 9fd1786..b553983 100644 --- a/src/src/drawstuff.cc +++ b/src/src/drawstuff.cc @@ -27,31 +27,16 @@ void gint_dhline(int x1, int x2, int y, uint16_t color) }; -void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B, uint8_t A ) +void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B ) { uint16_t color = C_RGB(R,G,B); for (int y=y1; y<=y2; y++) gint_dhline( 0, SCREEN_WIDTH, y, color ); }; -void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B, uint8_t A ) +void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B ) { -/* - uint16_t color = C_RGB(R,G,B); - float Ddeltay = 1.0f / (float) (y2-y1); - float deltay=0.0f; - for (int y=y1; y<=y2; y++) - { - if (y>0 && ycX); - fixed_t DY = (wY - c->cY); - fixed_t divDZ = fdiv( fix(1), (wZ - c->cZ)); + fixed_t DX = (fix(wX) - c->cX); + fixed_t DY = (fix(wY) - c->cY); + + fixed_t divDZ = fdiv( fix(1), (fixdouble(wZ) - c->cZ)); fixed_t RW = fix(ROAD_WIDTH); fixed_t divAR = fdiv(fix(1), fixdouble(ASPECT_RATIO)); - Scale = fmul(fixdouble(DISTANCE_SCREEN), divDZ); + fixed_t Scale = fmul(fixdouble(DISTANCE_SCREEN), divDZ); fixed_t tempx = fmul(fmul(DX,Scale), divAR); fixed_t tempy = fmul(DY, Scale); fixed_t tempw = fmul(fmul(RW,Scale), divAR); - sX=fmul(fix(SCREEN_CX), (fix(1)+tempx)); - sY=fmul(fix(SCREEN_CY), (fix(1)-tempy)); - sW=fmul(fix(SCREEN_CX), tempw); + fixed_t sX=fmul(fix(SCREEN_CX), (fix(1)+tempx)); + fixed_t sY=fmul(fix(SCREEN_CY), (fix(1)-tempy)); + fixed_t sW=fmul(fix(SCREEN_CX), tempw); X=fround(sX); Y=fround(sY);