313 lines
6.5 KiB
C++
313 lines
6.5 KiB
C++
#include <iostream>
|
|
#include <SDL.h>
|
|
#include <math.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/shm.h>
|
|
#include "sdlcommon.h"
|
|
#include "car.h"
|
|
#include "shmdata.h"
|
|
|
|
using namespace std;
|
|
|
|
Car::Car()
|
|
{
|
|
initShm();
|
|
reset();
|
|
showbar=1;
|
|
angstep=5;
|
|
for(int i=0;i<CAMVECT;i++) camera[i]=0;
|
|
carimage=0;
|
|
for(int i=0;i<TRAINEESIZE;i++) { trainee[i][0]=0; trainee[i][1]=0; }
|
|
traineepos=0;
|
|
traineesize=1;
|
|
}
|
|
|
|
void Car::loadImage(char *imagefile)
|
|
{
|
|
SDL_Surface *voitsurf;
|
|
Uint32 cur=SDL_GetTicks();
|
|
voitsurf=SDL_LoadBMP(imagefile);
|
|
printf("Precaching Surfaces ..... \n");
|
|
for(int i=0;i<360;i++)
|
|
{
|
|
Surface_car[i]=SDL_CreateRGBSurface(SDL_HWSURFACE, voitsurf->w, voitsurf->h, 32, 0,0,0,0);
|
|
if(SDL_SetColorKey(Surface_car[i], SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(Surface_car[i]->format, 255,0,255)) == -1)
|
|
fprintf(stderr, "Warning: colorkey will not be used, reason: %s\n", SDL_GetError());
|
|
rotatesurface(voitsurf,Surface_car[i],i);
|
|
}
|
|
carimage=1;
|
|
printf("Done ... (%d ms)\n",SDL_GetTicks()-cur);
|
|
}
|
|
|
|
void Car::updateCar(SDL_Surface* screen)
|
|
{
|
|
int i;
|
|
for(i=0;(SData->read!=0) && i<200;i++) usleep(5); // on attends 1 seconde
|
|
if(i==200)
|
|
{
|
|
cout << "AutoPilot Timed Out ...";
|
|
exit(0);
|
|
}
|
|
if(SData->Res[0]) decAngle();
|
|
if(SData->Res[1]) incAngle();
|
|
SData->Res[0]=0;
|
|
SData->Res[1]=0;
|
|
SData->pos_x+=getSpeed()*(cos(SData->angle*PI/180));
|
|
SData->pos_y+=getSpeed()*(sin(SData->angle*PI/180));
|
|
showTrainee(screen);
|
|
showCamera(screen); /* obligé pour avoir les pixels :-) */
|
|
// CAMERASIZE // CAMERASTEP
|
|
if(carimage) /* on blit la voiture */
|
|
{
|
|
SDL_Rect r;
|
|
r.w=Surface_car[SData->angle]->w;
|
|
r.h=Surface_car[SData->angle]->h;
|
|
r.x=(int)SData->pos_x-(r.w/2);
|
|
r.y=(int)SData->pos_y-(r.h/2);
|
|
SDL_BlitSurface( Surface_car[SData->angle], NULL, screen, &r);
|
|
}
|
|
else for(int i=0;i<20;i++) /* affichage de la voiture simplifiée (ligne rouge) */
|
|
{
|
|
setpixel(screen,(int)(SData->pos_x-(cos(SData->angle*PI/180)*i)),(int)( SData->pos_y-(sin(SData->angle*PI/180)*i)),255,0,0);
|
|
}
|
|
for(int i=0;i<CAMVECT;i++)
|
|
{
|
|
// cout << camera[i];
|
|
SData->V[i]=camera[i];
|
|
}
|
|
SData->read=1; /* on a lu :D */
|
|
//cout << endl;
|
|
}
|
|
|
|
void Car::showTrainee(SDL_Surface* screen)
|
|
{
|
|
int k;
|
|
trainee[traineepos][0]=(int)SData->pos_x;
|
|
trainee[traineepos][1]=(int)SData->pos_y;
|
|
traineepos=(traineepos+1)%traineesize;
|
|
k=traineepos;
|
|
k=(k+1)%traineesize;
|
|
for(int i=0; /*i < traineesize &&*/ k!=traineepos;i++) /* affichage de la trainée */
|
|
{
|
|
//setpixel(screen,trainee[k][0],trainee[k][1],0,(int)(i*(256.0/traineesize))%256,255);
|
|
int x0,y0,x1,y1;
|
|
x0=trainee[(k+traineesize-1)%traineesize][0];
|
|
y0=trainee[(k+traineesize-1)%traineesize][1];
|
|
x1=trainee[k][0];
|
|
y1=trainee[k][1];
|
|
if(x0==0) x0=x1;
|
|
if(y0==0) y0=y1;
|
|
if(x1==0) x1=x0;
|
|
if(y1==0) y1=y0;
|
|
DrawLine(screen,x0,y0,x1,y1,0,0,255);
|
|
k=(k+1)%traineesize;
|
|
}
|
|
|
|
}
|
|
|
|
void Car::showCamera(SDL_Surface* screen)
|
|
{
|
|
double x,y;
|
|
int k,ang;
|
|
x=SData->pos_x + ( cos(SData->angle*PI/180) * CAMERADISTANCE );
|
|
y=SData->pos_y + ( sin(SData->angle*PI/180) * CAMERADISTANCE );
|
|
ang=(SData->angle+90)%360;
|
|
x-=CAMERASIZE/2*cos(ang*PI/180);
|
|
y-=CAMERASIZE/2*sin(ang*PI/180);
|
|
k=0;
|
|
for(int i=0;i<CAMERASIZE;i++)
|
|
{
|
|
x+=cos(ang*PI/180);
|
|
y+=sin(ang*PI/180);
|
|
if(!(i%CAMERASTEP))
|
|
{
|
|
camera[k]=1;
|
|
if(inCarArea(screen,(int)x,(int)y)) //if(x>0 && x<screen->w && y>0 && y<screen->h)
|
|
camera[k]=(((getpixel(screen,(int)x,(int)y))%2)+1)%2;
|
|
else camera[k]=0;
|
|
|
|
if(camera[k] && showbar)
|
|
{
|
|
setpixel(screen, (int)x, (int)y,255,0,0);
|
|
//setpixel(screen, (int)x, (int)y-1,255,0,0);
|
|
//setpixel(screen, (int)x-1, (int)y,255,0,0);
|
|
//setpixel(screen, (int)x-1, (int)y-1,255,0,0);
|
|
}
|
|
else if(showbar)
|
|
{
|
|
setpixel(screen, (int)x, (int)y,0,255,0);
|
|
//setpixel(screen, (int)x, (int)y-1,0,255,0);
|
|
//setpixel(screen, (int)x-1, (int)y,0,255,0);
|
|
//setpixel(screen, (int)x-1, (int)y-1,0,255,0);
|
|
}
|
|
k++;
|
|
}
|
|
else
|
|
{
|
|
if(showbar) setpixel(screen, (int)x, (int)y,0,0,255);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Car::incAngle()
|
|
{
|
|
SData->angle=(SData->angle+angstep)%360;
|
|
}
|
|
void Car::decAngle()
|
|
{
|
|
SData->angle=(SData->angle+360-angstep)%360;
|
|
}
|
|
int Car::incAngleStep(int i)
|
|
{
|
|
angstep+=i;
|
|
return angstep;
|
|
}
|
|
void Car::incSpeed()
|
|
{
|
|
if(SData->Res[2]==0)
|
|
{
|
|
SData->Res[0]=0;
|
|
SData->Res[1]=0;
|
|
SData->Res[2]=1;
|
|
if(SData->speed==0) SData->speed=1;
|
|
}
|
|
SData->speed++;
|
|
}
|
|
void Car::decSpeed()
|
|
{
|
|
SData->speed--;
|
|
}
|
|
bool Car::APToggle()
|
|
{
|
|
SData->APon=(SData->APon+1)%2;
|
|
return SData->APon;
|
|
}
|
|
|
|
bool Car::APState() const
|
|
{
|
|
return SData->APon;
|
|
}
|
|
bool Car::neurToggle()
|
|
{
|
|
SData->Neuron=(SData->Neuron+1)%2;
|
|
return SData->Neuron;
|
|
}
|
|
|
|
bool Car::neurState() const
|
|
{
|
|
return SData->Neuron;
|
|
}
|
|
void Car::initShm()
|
|
{
|
|
if ((shmid = shmget(SHMKEY, sizeof(struct shmdata), 0666)) < 0)
|
|
{
|
|
perror("shmget");
|
|
exit(1);
|
|
}
|
|
if (( SData = (struct shmdata *)shmat(shmid, NULL, 0)) == (struct shmdata *) -1)
|
|
{
|
|
perror("shmat");
|
|
exit(1);
|
|
}
|
|
}
|
|
int Car::getSpeed() const
|
|
{
|
|
if(SData->Res[2])
|
|
return SData->speed;
|
|
return 0;
|
|
}
|
|
int Car::getAngle() const
|
|
{
|
|
return SData->angle;
|
|
}
|
|
bool Car::showBar(int i)
|
|
{
|
|
showbar=(showbar+i)%2;
|
|
return showbar;
|
|
}
|
|
bool* Car::getVect()
|
|
{
|
|
return SData->Res;
|
|
}
|
|
bool* Car::getView()
|
|
{
|
|
return SData->V;
|
|
}
|
|
void Car::reset()
|
|
{
|
|
SData->pos_x=200;
|
|
SData->pos_y=200;
|
|
SData->speed=1;
|
|
SData->angle=0;
|
|
SData->Res[2]=1;
|
|
}
|
|
void Car::turn180()
|
|
{
|
|
SData->angle=(SData->angle+180)%360;
|
|
}
|
|
int Car::incTraineeSize(int s)
|
|
{
|
|
int i,k;
|
|
if(s==0) return traineesize;
|
|
if(traineesize==1 && s<0) return traineesize;
|
|
if(traineesize+s > TRAINEESIZE) s=TRAINEESIZE-traineesize-1;
|
|
if(traineesize+s < 0) s=1-TRAINEESIZE;
|
|
int tmp[traineesize+s][2];
|
|
k=traineepos;
|
|
if(s<0) k=(traineesize+traineepos-s)%traineesize;
|
|
for(i=0;i<(traineesize+s);i++)
|
|
{
|
|
if(i>traineesize)
|
|
{
|
|
tmp[i][0]=0;
|
|
tmp[i][1]=0;
|
|
}
|
|
else
|
|
{
|
|
tmp[i][0]=trainee[k][0];
|
|
tmp[i][1]=trainee[k][1];
|
|
}
|
|
k=(k+1)%traineesize;
|
|
}
|
|
for(i=0;i<traineesize+s;i++)
|
|
{
|
|
trainee[i][0]=tmp[i][0];
|
|
trainee[i][1]=tmp[i][1];
|
|
}
|
|
traineepos=traineesize-1;
|
|
// if(traineesize<1) { traineesize=1; traineepos=0; }
|
|
if(s<0)traineepos=0;
|
|
traineesize+=s;
|
|
return traineesize;
|
|
}
|
|
void Car::setDelay(int del)
|
|
{
|
|
SData->delay=del;
|
|
}
|
|
void Car::harakiri()
|
|
{
|
|
cout << " EXIT INTERFACE ...\n";
|
|
SData->read=666;
|
|
usleep(100);
|
|
SData->read=666;
|
|
usleep(100);
|
|
SData->read=666;
|
|
}
|
|
void Car::saveState()
|
|
{
|
|
SData->action=SAVE_STATE;
|
|
}
|
|
void Car::loadState()
|
|
{
|
|
SData->action=RELOAD_STATE;
|
|
}
|
|
void Car::showNetwork(bool a)
|
|
{
|
|
SData->viewNetwork=a;
|
|
}
|
|
bool Car::showNetworkState()
|
|
{
|
|
return SData->viewNetwork;
|
|
}
|