Update Rendering for Speed

This commit is contained in:
Sylvain PILLOT 2022-03-04 21:58:14 +01:00
commit e3bdbaf171
30 changed files with 948 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# Build files
/build-fx
/build-cg
/*.g1a
/*.g3a
# Python bytecode
__pycache__/
# Common IDE files
*.sublime-project
*.sublime-workspace
.vscode

42
CMakeLists.txt Normal file
View File

@ -0,0 +1,42 @@
# Configure with [fxsdk build-cg], which provide the
# toolchain file and module path of the fxSDK
cmake_minimum_required(VERSION 3.15)
project(MyAddin)
include(GenerateG3A)
include(Fxconv)
find_package(Gint 2.7.0 REQUIRED)
find_package(LibProf 2.4 REQUIRED)
set(SOURCES
src/main.cc
src/src/segment.cc
src/src/camera.cc
src/src/circuit.cc
src/src/drawstuff.cc
# ...
)
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
)
fxconv_declare_assets(${ASSETS_cg} WITH_METADATA)
add_executable(myaddin ${SOURCES} ${ASSETS_${FXSDK_PLATFORM}})
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -std=c++11 -c -fno-rtti -fno-use-cxa-atexit -fpermissive)
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
NAME "OutRunFP" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
endif()

46
CppOutRun.cbp Normal file
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="CppOutRun" />
<Option pch_mode="2" />
<Option compiler="null" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/CppOutRun" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="null" />
<Compiler>
<Add directory="src/include" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/CppOutRun" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="null" />
<Compiler>
<Add directory="src/include" />
</Compiler>
</Target>
</Build>
<Unit filename="CMakeLists.txt" />
<Unit filename="assets-cg/fxconv-metadata.txt" />
<Unit filename="assets-cg/traffic/fxconv-metadata.txt" />
<Unit filename="src/fixed.h" />
<Unit filename="src/include/camera.h" />
<Unit filename="src/include/circuit.h" />
<Unit filename="src/include/drawstuff.h" />
<Unit filename="src/include/segment.h" />
<Unit filename="src/main.cc" />
<Unit filename="src/parameters.h" />
<Unit filename="src/src/camera.cc" />
<Unit filename="src/src/circuit.cc" />
<Unit filename="src/src/drawstuff.cc" />
<Unit filename="src/src/segment.cc" />
<Extensions>
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

50
CppOutRun.layout Normal file
View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<FileVersion major="1" minor="0" />
<ActiveTarget name="Release" />
<File name="src/include/camera.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="221" topLine="0" />
</Cursor>
</File>
<File name="src/include/segment.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="265" topLine="0" />
</Cursor>
</File>
<File name="src/src/circuit.cc" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="406" topLine="54" />
</Cursor>
</File>
<File name="src/fixed.h" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="597" topLine="44" />
</Cursor>
</File>
<File name="src/src/segment.cc" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="2" zoom_2="0">
<Cursor>
<Cursor1 position="169" topLine="0" />
</Cursor>
</File>
<File name="src/parameters.h" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="189" topLine="0" />
</Cursor>
</File>
<File name="CMakeLists.txt" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="759" topLine="1" />
</Cursor>
</File>
<File name="src/main.cc" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="1" zoom_2="0">
<Cursor>
<Cursor1 position="5592" topLine="181" />
</Cursor>
</File>
<File name="src/src/camera.cc" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="124" topLine="0" />
</Cursor>
</File>
</CodeBlocks_layout_file>

45
README.md Normal file
View File

@ -0,0 +1,45 @@
# OutRun : a simple race game for Casio Graph 90+E
OutRun is a very simple race game based on the classical Outrun-type license, very famous in the 90's.
The purpose of the game is to drive as fast as possible on various highways, in the middle of the traffic.
## Installing and compiling the game
Provided you would like to compile the game Addin, starting from the code, some prerequities are mandatory :
- `fxlibc` in its `@dev` version is mandatory (to get correct implementation of <errno.h>)
- `µSTL` is also mandatory
- `libprof` is also needed to get accurate timing
**Installing with GiteaPC**
`fxlibc` can be installed using GiteaPC by using
```Bash
% giteapc install Vhex-Kernel-Core/fxlibc@dev
```
`µSTL` can then be installed by typing in a terminal
```Bash
% giteapc install Slyvtt/uSTL_2.3
```
`libprof` can be built and installed with
```bash
% giteapc install Lephenixnoir/libprof
```
**Compiling**
Simply run `fxsdk build-cg`. The fxSDK will invoke CMake with a suitable toolchain file while exposing CMake modules for the calculator.
```bash
% fxsdk build-cg
```
Please note that currently there is no compile target for `fx-9860G`

View File

@ -0,0 +1,5 @@
#*.png:
# type: bopti-image
# profile: p4
# name_regex: (.*)\.png \1

BIN
assets-cg/icon-sel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
assets-cg/icon-uns.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets-cg/traffic/car1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

BIN
assets-cg/traffic/car2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

BIN
assets-cg/traffic/car3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

BIN
assets-cg/traffic/car4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 B

BIN
assets-cg/traffic/car5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 B

BIN
assets-cg/traffic/car6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 B

BIN
assets-cg/traffic/car7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

BIN
assets-cg/traffic/car8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 B

View File

@ -0,0 +1,5 @@
*.png:
type: bopti-image
profile: p4
name_regex: (.*)\.png \1

3
build Executable file
View File

@ -0,0 +1,3 @@
rm -r build-cg
rm *.g3a
fxsdk build-cg VERBOSE=1

2
clean Executable file
View File

@ -0,0 +1,2 @@
rm -r build-cg/
rm *.g3a

86
src/fixed.h Normal file
View File

@ -0,0 +1,86 @@
//---
// fixed: 16:16 fixed-point arithmetic
//---
#pragma once
#include <stdint.h>
typedef int64_t fixed_t;
//extended from initial int32_t
/* Standard arithmetic. */
static inline fixed_t fmul(fixed_t left, fixed_t right)
{
/* Generally optimized by the compiler to use dmuls.l and xtrct */
int64_t p = (int64_t)left * (int64_t)right;
return (int32_t)(p >> 16);
}
static inline fixed_t fdiv(fixed_t left, fixed_t right)
{
/* Pretty slow */
int64_t d = (int64_t)left << 16;
return d / right;
}
#define fix(x) ((int)((x) * 65536))
static inline fixed_t fixdouble(long double constant)
{
return (fixed_t)(constant * 65536);
}
static inline fixed_t fixfloat(float constant)
{
return (fixed_t)(constant * 65536);
}
static inline fixed_t fdec(fixed_t f)
{
return f & 0xffff;
}
static inline int ffloor(fixed_t f)
{
return f >> 16;
}
static inline int fceil(fixed_t f)
{
return (f + 0xffff) >> 16;
}
static inline int fround(fixed_t f)
{
return (f + 0x8000) >> 16;
}
static inline float f2float(fixed_t f)
{
return (float)f / 65536;
}
static inline double f2double(fixed_t f)
{
return (double)f / 65536;
}
static inline double f2int(fixed_t f)
{
return (int)f / 65536;
}
static inline fixed_t feasein(fixed_t x)
{
return fmul(x, x);
}
static inline fixed_t fease(fixed_t x)
{
if(x <= fix(0.5)) {
return 2 * fmul(x, x);
}
else {
x = fix(1) - x;
return fix(1) - 2 * fmul(x, x);
}
}

26
src/include/camera.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef CAMERA_H
#define CAMERA_H
#include "../fixed.h"
class camera
{
public:
camera();
camera( double x, double y, double z);
~camera();
void incX( double dx );
void incY( double dy );
void incZ( double dz );
void decX( double dx );
void decY( double dy );
void decZ( double dz );
fixed_t cX = 0;
fixed_t cY = 0;
fixed_t cZ = 0;
};
#endif // CAMERA_H

12
src/include/circuit.h Normal file
View File

@ -0,0 +1,12 @@
#include <vector>
void initData( void );
void createCircuit( void );
void projectCircuitFP( void );
void projectCircuitFP( uint16_t index );
void printCircuit( void );
void printCircuit( int i );
void drawCircuitSegment( uint16_t index );

9
src/include/drawstuff.h Normal file
View File

@ -0,0 +1,9 @@
#include <gint/defs/types.h>
#include <gint/defs/util.h>
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 drawSky( void );
void drawSky( int ymin, int ymax );

26
src/include/segment.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef SEGMENT_H
#define SEGMENT_H
#include "../fixed.h"
#include <stdint.h>
#include "camera.h"
class Segment
{
public:
Segment();
Segment( uint16_t n_seg );
~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;
};
#endif // SEGMENT_H

243
src/main.cc Normal file
View File

@ -0,0 +1,243 @@
#include <gint/display.h>
#include <gint/drivers/r61524.h>
#include <gint/keyboard.h>
#include <gint/gint.h>
#include <gint/defs/types.h>
#include <fxlibc/printf.h>
#include <libprof.h>
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>
#include <math.h>
#include <vector>
#include <array>
#include "include/camera.h"
#include "include/segment.h"
#include "parameters.h"
#include "include/circuit.h"
#include "include/drawstuff.h"
//extern bopti_image_t car1, car2, car3, car4, car5, car6, car7, car8;
std::vector<Segment*> circuit;
camera *cam;
bool stop = false;
bool record = false;
bool screenshot = false;
uint16_t currentcurve=0;
uint8_t shiftcolor=0;
float speed = 0;
float maxspeedforward = 8;
float maxspeedbackward = 4;
int direction = 1;
bool speedcontrol = false;
static void get_inputs( float dt )
{
key_event_t ev;
while((ev = pollevent()).type != KEYEV_NONE)
{
}
speedcontrol = false;
if(keydown(KEY_LEFT)) cam->decX(25.0);
if(keydown(KEY_RIGHT)) cam->incX(25.0);
if(keydown(KEY_SHIFT))
{
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))
{
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_7)) cam->incY(10.0);
//if(keydown(KEY_1)) cam->decY(10.0);
//if(keydown(KEY_MENU)) gint_osmenu();
if(keydown(KEY_EXIT)) stop = true;
if(keydown(KEY_F6)) record = !record;
if(keydown(KEY_F4)) screenshot = true;
if (speedcontrol==false)
{
speed-=0.3;
if (speed<0) speed=0;
if (direction==1)
cam->incZ(speed*dt);
else
cam->decZ(speed*dt);
}
}
int main(void)
{
__printf_enable_fp();
__printf_enable_fixed();
usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL };
usb_open(interfaces, GINT_CALL_NULL);
prof_t perf_create, perf_project, perf_render;
uint32_t time_create=0, time_project=0, time_render=0;
prof_init();
int nbInterestingSegments = (MAX_RENDER_DISTANCE / SEGMENT_LENGTH) + 10; // the number of segments to be projected considering the rendering distance
//--------------
initData( );
//--------------
perf_create = prof_make();
prof_enter(perf_create);
createCircuit();
prof_leave(perf_create);
time_create = prof_time(perf_create);
//--------------
int indexstart = 0;
uint32_t maxDistance = (MAX_SEGMENT-nbInterestingSegments-5)*SEGMENT_LENGTH;
uint32_t dt=0;
uint16_t l=0;
while (!stop)
{
get_inputs( dt );
dt = ((float) (time_render+time_project) / 1000.0);
//--------------
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;
// 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;
//--------------
perf_project = prof_make();
prof_enter(perf_project);
for (int k=indexstart; k<indexstart+nbInterestingSegments+1; k++) // Need to project 1 more segment than actual drawing
projectCircuitFP( k );
prof_leave(perf_project);
time_project = prof_time(perf_project);
//--------------
perf_render = prof_make();
prof_enter(perf_render);
drawSky( );
for (int k=indexstart; k<indexstart+nbInterestingSegments; k++)
{
drawCircuitSegment( k );
}
//r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT);
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 );
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() );
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( 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 );
//r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT);
dupdate();
prof_leave(perf_render);
time_render = prof_time(perf_render);
if (screenshot && usb_is_open())
{
usb_fxlink_screenshot(true);
screenshot = false;
}
if(record && usb_is_open())
{
usb_fxlink_videocapture(false);
}
l++;
}
prof_quit();
usb_close();
circuit.clear();
delete cam;
return 1;
}

24
src/parameters.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef PARAMETERS_H
#define PARAMETERS_H
#define SCREEN_WIDTH 396
#define SCREEN_HEIGHT 224
#define SCREEN_CX 198
#define SCREEN_CY 112
#define SEGMENT_LENGTH 200
#define ROAD_WIDTH 600
#define ASPECT_RATIO 1.767
#define DISTANCE_SCREEN 0.83444
#define MAX_RENDER_DISTANCE 1500
#define MAX_SEGMENT 10000
#define std ustl
#endif // PARAMETERS_H

54
src/src/camera.cc Normal file
View File

@ -0,0 +1,54 @@
#include "../include/camera.h"
camera::camera()
{
//ctor
}
camera::camera( double x, double y, double z)
{
cX = fixdouble( x );
cY = fixdouble( y );
cZ = fixdouble( z );
}
camera::~camera()
{
//dtor
}
void camera::incX( double dx )
{
cX += fixdouble( dx );
};
void camera::incY( double dy )
{
cY += fixdouble( dy );
};
void camera::incZ( double dz )
{
cZ += fixdouble( dz );
};
void camera::decX( double dx )
{
cX -= fixdouble( dx );
};
void camera::decY( double dy )
{
cY -= fixdouble( dy );
};
void camera::decZ( double dz )
{
cZ -= fixdouble( dz );
};

117
src/src/circuit.cc Normal file
View File

@ -0,0 +1,117 @@
#include "../include/circuit.h"
#include "../include/segment.h"
#include "../include/camera.h"
#include "../parameters.h"
#include <gint/display.h>
#include "../include/drawstuff.h"
extern std::vector<Segment*> circuit;
extern camera *cam;
extern uint16_t currentcurve;
extern uint8_t shiftcolor;
void initData( void )
{
cam = new camera();
cam->cX = fixdouble(0.0f);
cam->cY = fixdouble(300.0f);
cam->cZ = fixdouble(260.0f);
}
void createCircuit( void )
{
for( int i=0; i<MAX_SEGMENT; i++)
{
Segment *s=new Segment( i );
circuit.push_back( s );
}
};
void projectCircuitFP( void )
{
for( int i=0; i<circuit.size(); i++)
{
circuit[i]->Project3DFP( cam );
}
};
void projectCircuitFP( uint16_t index )
{
circuit[index]->Project3DFP( cam );
};
void printCircuit( void )
{
for( int i=0; i<20; i++)
{
dprint(198, 1+10*(i), C_RED, "%d-(sX,Y,W)=(%d,%d,%d)", i, circuit[i]->X, 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 );
}
};
void printCircuit( int i )
{
dprint(1, 1+10*(i), C_RED, "%d-(wX,Y,Z)=(%d,%d,%d)", i, fround(circuit[i]->wX), fround(circuit[i]->wY), fround(circuit[i]->wZ) );
dprint(198, 1+10*(i), C_RED, "%d-(sX,Y,W)=(%d,%d,%d)", i, circuit[i]->X, circuit[i]->Y, circuit[i]->W );
};
void drawCircuitSegment( uint16_t index )
{
if (index>=circuit.size()-1) return;
int X1 = (int) circuit[index]->X;
int Y1 = (int) circuit[index]->Y;
int W1 = (int) circuit[index]->W;
int X2 = (int) circuit[(index+1)]->X + circuit[index]->Curve;
int Y2 = (int) circuit[(index+1)]->Y;
int W2 = (int) circuit[(index+1)]->W;
if (Y1==Y2) return;
if (index%2==0)
{
drawGrass( Y2, Y1, 0, 255-shiftcolor, 45-shiftcolor, 255 );
// route
drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 196-shiftcolor, 196-shiftcolor, 196-shiftcolor, 255 );
// 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 );
// 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 );
// 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 );
// 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 );
// 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 );
// 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 );
}
else
{
drawGrass( Y2, Y1, 0, 255-shiftcolor, 0, 255 );
drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 180-shiftcolor, 180-shiftcolor, 180-shiftcolor, 255 );
// 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 );
// 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 );
}
currentcurve += circuit[index]->Curve;
}

94
src/src/drawstuff.cc Normal file
View File

@ -0,0 +1,94 @@
#include "../include/drawstuff.h"
#include "../parameters.h"
#include <gint/display.h>
#include "../fixed.h"
void gint_dhline(int x1, int x2, int y, uint16_t color)
{
if((uint)y >= 224) return;
if(x1 > x2) swap(x1, x2);
if(x1 >= 396 || x2 < 0) return;
if(x1 < 0) x1 = 0;
if(x2 >= 396) x2 = 395;
int offset = 396 * y;
gint_vram[offset + x1] = color;
gint_vram[offset + x2] = color;
x1 = x1 + (x1 & 1);
x2 = (x2 + 1) & ~1;
uint32_t *start = (void *)(gint_vram + offset + x1);
uint32_t *end = (void *)(gint_vram + offset + x2);
uint32_t op = (color << 16) | color;
while(end > start) *--end = op;
};
void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B, uint8_t A )
{
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 )
{
/*
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 && y<SCREEN_HEIGHT)
{
float xmin = (float) x1min + (float) (x2min-x1min)*deltay;
float xmax = (float) x1max + (float) (x2max-x1max)*deltay;
gint_dhline( (int) xmin, (int) xmax, y, color );
}
deltay+=Ddeltay;
}
*/
uint16_t color = C_RGB(R,G,B);
if (y1==y2)
{
gint_dhline( x1min, x1max, y1, color );
return;
}
//fixed_t Ddeltay = fdiv(fix(1), fix(y2-y1));
//fixed_t deltay = 0;
fixed_t deltay = fdiv(fix(1), fix(y2-y1));
fixed_t xmin = fix(x1min);
fixed_t xmax = fix(x1max);
fixed_t dxmin = fix(x2min-x1min);
fixed_t dxmax = fix(x2max-x1max);
for (int y=y1; y<=y2; y++)
{
if (y>0 && y<SCREEN_HEIGHT)
{
xmin += fmul(deltay, dxmin);
xmax += fmul(deltay, dxmax);
gint_dhline( fround(xmin), fround(xmax), y, color );
}
//deltay+=Ddeltay;
}
};
void drawSky( void )
{
dclear( C_RGB(0,45,255) );
};
void drawSky( int ymin, int ymax )
{
uint16_t color = C_RGB(0,45,255);
for(int y=ymin; y<=ymax; y++ )
gint_dhline( 0, SCREEN_WIDTH, y, color );
};

46
src/src/segment.cc Normal file
View File

@ -0,0 +1,46 @@
#include "../include/segment.h"
#include "../parameters.h"
Segment::Segment()
{
//ctor
}
Segment::Segment( uint16_t n_seg )
{
wX = 0;
wY = 0;
wZ = fixdouble((400 + n_seg * SEGMENT_LENGTH));
}
Segment::~Segment()
{
//dtor
}
void Segment::Project3DFP( camera* c )
{
fixed_t DX = (wX - c->cX);
fixed_t DY = (wY - c->cY);
fixed_t divDZ = fdiv( fix(1), (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 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);
X=fround(sX);
Y=fround(sY);
W=fround(sW);
}