commit e3bdbaf1715bbd2082591a0830f1759d91065d3a Author: Slyvtt Date: Fri Mar 4 21:58:14 2022 +0100 Update Rendering for Speed diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c4f84b --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Build files +/build-fx +/build-cg +/*.g1a +/*.g3a + +# Python bytecode + __pycache__/ + +# Common IDE files +*.sublime-project +*.sublime-workspace +.vscode diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bf91817 --- /dev/null +++ b/CMakeLists.txt @@ -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() diff --git a/CppOutRun.cbp b/CppOutRun.cbp new file mode 100644 index 0000000..259bbe9 --- /dev/null +++ b/CppOutRun.cbp @@ -0,0 +1,46 @@ + + + + + + diff --git a/CppOutRun.layout b/CppOutRun.layout new file mode 100644 index 0000000..03b2e38 --- /dev/null +++ b/CppOutRun.layout @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..de31dc3 --- /dev/null +++ b/README.md @@ -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 ) + - `µ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` + + diff --git a/assets-cg/fxconv-metadata.txt b/assets-cg/fxconv-metadata.txt new file mode 100644 index 0000000..fc1422a --- /dev/null +++ b/assets-cg/fxconv-metadata.txt @@ -0,0 +1,5 @@ +#*.png: +# type: bopti-image +# profile: p4 +# name_regex: (.*)\.png \1 + diff --git a/assets-cg/icon-sel.png b/assets-cg/icon-sel.png new file mode 100644 index 0000000..44b7006 Binary files /dev/null and b/assets-cg/icon-sel.png differ diff --git a/assets-cg/icon-uns.png b/assets-cg/icon-uns.png new file mode 100644 index 0000000..fdd20ad Binary files /dev/null and b/assets-cg/icon-uns.png differ diff --git a/assets-cg/traffic/car1.png b/assets-cg/traffic/car1.png new file mode 100644 index 0000000..2eac8c6 Binary files /dev/null and b/assets-cg/traffic/car1.png differ diff --git a/assets-cg/traffic/car2.png b/assets-cg/traffic/car2.png new file mode 100644 index 0000000..e580e16 Binary files /dev/null and b/assets-cg/traffic/car2.png differ diff --git a/assets-cg/traffic/car3.png b/assets-cg/traffic/car3.png new file mode 100644 index 0000000..e2d77ea Binary files /dev/null and b/assets-cg/traffic/car3.png differ diff --git a/assets-cg/traffic/car4.png b/assets-cg/traffic/car4.png new file mode 100644 index 0000000..4e7a102 Binary files /dev/null and b/assets-cg/traffic/car4.png differ diff --git a/assets-cg/traffic/car5.png b/assets-cg/traffic/car5.png new file mode 100644 index 0000000..e8fd59e Binary files /dev/null and b/assets-cg/traffic/car5.png differ diff --git a/assets-cg/traffic/car6.png b/assets-cg/traffic/car6.png new file mode 100644 index 0000000..76f6a1a Binary files /dev/null and b/assets-cg/traffic/car6.png differ diff --git a/assets-cg/traffic/car7.png b/assets-cg/traffic/car7.png new file mode 100644 index 0000000..8e0b590 Binary files /dev/null and b/assets-cg/traffic/car7.png differ diff --git a/assets-cg/traffic/car8.png b/assets-cg/traffic/car8.png new file mode 100644 index 0000000..66f618d Binary files /dev/null and b/assets-cg/traffic/car8.png differ diff --git a/assets-cg/traffic/fxconv-metadata.txt b/assets-cg/traffic/fxconv-metadata.txt new file mode 100644 index 0000000..7e05b58 --- /dev/null +++ b/assets-cg/traffic/fxconv-metadata.txt @@ -0,0 +1,5 @@ +*.png: + type: bopti-image + profile: p4 + name_regex: (.*)\.png \1 + diff --git a/build b/build new file mode 100755 index 0000000..1f9dd05 --- /dev/null +++ b/build @@ -0,0 +1,3 @@ +rm -r build-cg +rm *.g3a +fxsdk build-cg VERBOSE=1 diff --git a/clean b/clean new file mode 100755 index 0000000..0c58279 --- /dev/null +++ b/clean @@ -0,0 +1,2 @@ +rm -r build-cg/ +rm *.g3a diff --git a/src/fixed.h b/src/fixed.h new file mode 100644 index 0000000..3568d11 --- /dev/null +++ b/src/fixed.h @@ -0,0 +1,86 @@ +//--- +// fixed: 16:16 fixed-point arithmetic +//--- +#pragma once +#include +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); + } +} diff --git a/src/include/camera.h b/src/include/camera.h new file mode 100644 index 0000000..62c527d --- /dev/null +++ b/src/include/camera.h @@ -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 diff --git a/src/include/circuit.h b/src/include/circuit.h new file mode 100644 index 0000000..6816b7f --- /dev/null +++ b/src/include/circuit.h @@ -0,0 +1,12 @@ +#include + +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 ); diff --git a/src/include/drawstuff.h b/src/include/drawstuff.h new file mode 100644 index 0000000..5bb4992 --- /dev/null +++ b/src/include/drawstuff.h @@ -0,0 +1,9 @@ +#include +#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 drawSky( void ); +void drawSky( int ymin, int ymax ); diff --git a/src/include/segment.h b/src/include/segment.h new file mode 100644 index 0000000..c6e507a --- /dev/null +++ b/src/include/segment.h @@ -0,0 +1,26 @@ +#ifndef SEGMENT_H +#define SEGMENT_H + +#include "../fixed.h" +#include +#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 diff --git a/src/main.cc b/src/main.cc new file mode 100644 index 0000000..52d81c9 --- /dev/null +++ b/src/main.cc @@ -0,0 +1,243 @@ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +#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 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; kcX ) ); + 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; +} diff --git a/src/parameters.h b/src/parameters.h new file mode 100644 index 0000000..8f1f6f4 --- /dev/null +++ b/src/parameters.h @@ -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 diff --git a/src/src/camera.cc b/src/src/camera.cc new file mode 100644 index 0000000..74b2bbf --- /dev/null +++ b/src/src/camera.cc @@ -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 ); +}; diff --git a/src/src/circuit.cc b/src/src/circuit.cc new file mode 100644 index 0000000..dbf5eab --- /dev/null +++ b/src/src/circuit.cc @@ -0,0 +1,117 @@ +#include "../include/circuit.h" +#include "../include/segment.h" +#include "../include/camera.h" +#include "../parameters.h" +#include + +#include "../include/drawstuff.h" + + +extern std::vector 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; iProject3DFP( 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; +} diff --git a/src/src/drawstuff.cc b/src/src/drawstuff.cc new file mode 100644 index 0000000..9fd1786 --- /dev/null +++ b/src/src/drawstuff.cc @@ -0,0 +1,94 @@ +#include "../include/drawstuff.h" +#include "../parameters.h" +#include +#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 && y0 && ycX); + 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); +}