- Joined
- Jan 18, 2010
- Messages
- 11,418
Well, I'm back at trying to port things.. I've got this game mostly running, I want to re-write the code that allows the user to redefine the keys since it's horribly designed.. but that's another issue.
What my real issue is I have some odd ground collision issues that are not apparent when compiled on x86. I'm a bit rusty in C since I haven't dove into it in a few years and have no real experience with SDL / game code in general.
So when I'm in air the game appears to work fine, but when on the ground and trying to take off.. the planes seem to hop and bounce around irratically. Preventing the plane from taking off. I think this may be a clipping issue or something. I have some clues to what may be the issue.. during compiling I'm getting some warnings that I'm not seeing when compiling on the x86.. I've tried playing with some of the flags.. tried using -02 instead of -03, disabling fast-math and single-precision-constant.. I've also tried giving the the variables a value of 0 to intialize them... but I reverted those changes as they didn't seem to help or hurt the game.. So I'm Just curious if I'm missing something simple. I'll share the compile warnings and the methods it's calling out.
So I'm looking for advice..
renderer.c:132:
mapping.c:211:
roads.c:142:
intro.c:269:
renderer.c:482:
roads.c:243:
What my real issue is I have some odd ground collision issues that are not apparent when compiled on x86. I'm a bit rusty in C since I haven't dove into it in a few years and have no real experience with SDL / game code in general.
So when I'm in air the game appears to work fine, but when on the ground and trying to take off.. the planes seem to hop and bounce around irratically. Preventing the plane from taking off. I think this may be a clipping issue or something. I have some clues to what may be the issue.. during compiling I'm getting some warnings that I'm not seeing when compiling on the x86.. I've tried playing with some of the flags.. tried using -02 instead of -03, disabling fast-math and single-precision-constant.. I've also tried giving the the variables a value of 0 to intialize them... but I reverted those changes as they didn't seem to help or hurt the game.. So I'm Just curious if I'm missing something simple. I'll share the compile warnings and the methods it's calling out.
So I'm looking for advice..
Code:
/usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-gcc -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -std=c99 -W -Wall -D_GNU_SOURCE -I/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -DDATADIR='"/mnt/utmp/fachoda-complex/data"' -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -c -o renderer.o renderer.c
renderer.c: In function 'polyflat':
renderer.c:132: warning: 'qx' may be used uninitialized in this function
renderer.c:132: warning: 'ql' may be used uninitialized in this function
renderer.c: In function 'renderer':
renderer.c:482: warning: 'e.x' may be used uninitialized in this function
renderer.c:482: warning: 'e.y' may be used uninitialized in this function
renderer.c:132:
Code:
int q1, q2, q3, ql, qx, qx2 = 0, ql2 = 0;
Code:
struct vect2d e;
Code:
/usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-gcc -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -std=c99 -W -Wall -D_GNU_SOURCE -I/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -DDATADIR='"/mnt/utmp/fachoda-complex/data"' -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -c -o mapping.o mapping.c
mapping.c: In function 'polyphong':
mapping.c:211: warning: 'py2' may be used uninitialized in this function
mapping.c:211: warning: 'px2' may be used uninitialized in this function
mapping.c:211: warning: 'py' may be used uninitialized in this function
mapping.c:211: warning: 'px' may be used uninitialized in this function
mapping.c:211: warning: 'ql2' may be used uninitialized in this function
mapping.c:211: warning: 'qx2' may be used uninitialized in this function
mapping.c:211: warning: 'qx' may be used uninitialized in this function
mapping.c:211: warning: 'ql' may be used uninitialized in this function
mapping.c:211:
Code:
int q1, q2, q3, ql, p1x, p1y, p2x, p2y, qx, qx2, ql2, px,py,px2,py2;
Code:
/usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-gcc -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -std=c99 -W -Wall -D_GNU_SOURCE -I/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -DDATADIR='"/mnt/utmp/fachoda-complex/data"' -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -c -o roads.o roads.c
roads.c: In function 'nxtrt':
roads.c:142: warning: 'besta.x' may be used uninitialized in this function
roads.c:142: warning: 'besta.y' may be used uninitialized in this function
roads.c:142: warning: 'besta.z' may be used uninitialized in this function
roads.c: In function 'prospectroute':
roads.c:243: warning: 'bestp1.x' may be used uninitialized in this function
roads.c:243: warning: 'bestp1.y' may be used uninitialized in this function
roads.c:243: warning: 'bestp1.z' may be used uninitialized in this function
roads.c:142:
Code:
struct vector r,besta,u;
Code:
struct vector p1,p2, bestp1, bestp2, v;
Code:
/usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-gcc -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -std=c99 -W -Wall -D_GNU_SOURCE -I/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -DDATADIR='"/mnt/utmp/fachoda-complex/data"' -DPANDORA -DHAVE_GLES -O3 -pipe -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -ffast-math -fsingle-precision-constant -fsigned-char -c -o intro.o intro.c
intro.c: In function 'present':
intro.c:269: warning: 'oldcurround' may be used uninitialized in this function
intro.c:269: warning: 'nextround' may be used uninitialized in this function
intro.c:269:
Code:
int curround = 0, oldcurround, nextround, etap = 2;
Code:
bool polyflat(struct vect2d *p1, struct vect2d *p2, struct vect2d *p3, struct pixel coul) {
struct vect2d *tmp;
int xi, yi, lx, i, j, jlim, yfin;
int q1, q2, q3, ql, qx, qx2 = 0, ql2 = 0;
struct pixel32 *vid;
if (p2->y<p1->y) { tmp=p1; p1=p2; p2=tmp; }
if (p3->y<p1->y) { tmp=p1; p1=p3; p3=tmp; }
if (p3->y<p2->y) { tmp=p2; p2=p3; p3=tmp; }
if (p1->y==p2->y && p1->x>p2->x) { tmp=p1; p1=p2; p2=tmp; }
if (p3->y<0 || p1->y>=win_height) return false;
// if (p3->y==p2->y) p3->y++;
// if (p1->y==p2->y) p1->y--;
yi=p1->y;
if (p3->y==p1->y) {
if (p1->x>p3->x) { tmp=p1; p1=p3; p3=tmp; }
if (p2->x<p3->x) { tmp=p2; p2=p3; p3=tmp; }
xi=p1->x<<vf;
lx = (p2->x - p1->x +1)<<vf;
yfin = yi+1;
goto debtrace;
}
lx = 1<<vf;
xi=p1->x<<vf;
q1=((p3->x-p1->x)<<vf)/(p3->y-p1->y); // et le cas p3y=p1y ?? maintenant il faut le traiter à part !
if (p1->y!=p2->y) {
q2=((p2->x-p1->x)<<vf)/(p2->y-p1->y);
} else { // on a forcément p1x<p2x
q2 = MAXINT;
lx = (p2->x-p1->x+1)<<vf;
}
if (p3->y!=p2->y) {
q3=((p3->x-p2->x)<<vf)/(p3->y-p2->y);
} else {
q3=MAXINT; // ou -MAXINT, mais comme on s'en sert pas..
}
if (q1<=q2) {
ql = (q2-q1)|1; // le taux d'accroissement de la taille du segment (en évitant 0);
ql2= q3-q1;
qx=qx2=q1;
} else {
ql = (q1-q2)|1;
ql2= q1-q3;
qx=q2; qx2=q3;
}
// clipper les y<0 ! sinon ca fait des pauses !
yfin=p2->y;
if (p2->y<0) {
xi+=(p2->y-p1->y)*qx;
yi=p2->y;
lx+=(p2->y-p1->y)*ql;
yfin=p3->y; ql=ql2; qx=qx2;
}
if (yi<0) {
xi-=yi*qx;
lx-=yi*ql;
yi=0;
}
debtrace:
vid=videobuffer+(yi)*win_width;
for (i=0; i<2; i++, yfin=p3->y, ql=ql2, qx=qx2){
while (yi<yfin && yi<win_height) {
jlim = (lx+xi)>>vf;
j = xi>>vf;
if (j < 0) j = 0;
if (jlim > win_width) jlim = win_width;
if (j < jlim) {
memset32((int*)(vid+j), color_of_pixel(coul), jlim-j);
}
xi += qx;
yi++;
lx += ql;
vid += win_width;
}
}
return true;
}
renderer.c:482:
B) ;
}
if (pts2d[mod[obj[o].model].fac[mo][p].p[0]].xl!=MAXINT && pts2d[mod[obj[o].model].fac[mo][p].p[1]].xl!=MAXINT && pts2d[mod[obj[o].model].fac[mo][p].p[2]].xl!=MAXINT)
polyphong(
&pts2d[mod[obj[o].model].fac[mo][p].p[0]],
&pts2d[mod[obj[o].model].fac[mo][p].p[1]],
&pts2d[mod[obj[o].model].fac[mo][p].p[2]],
coul);
else
polyflat(
&pts2d[mod[obj[o].model].fac[mo][p].p[0]].v,
&pts2d[mod[obj[o].model].fac[mo][p].p[1]].v,
&pts2d[mod[obj[o].model].fac[mo][p].p[2]].v,
coul);
}
}
}
}
}
}
}
}
if (night_mode && obj[o].type==TYPE_LIGHT) { // HALO
plotphare(e.x,e.y,rayonapparent*4+1);
}
}
}
}
if (fast!=1) { o=obj[o].prec; no--; } else o=obj[o].next;
} while (o!=-1);
}
static bool to_camera(struct vector const *v3d, struct vect2d *v2d)
{
struct vector vc = *v3d;
struct vector vc_c;
subv(&vc, &obj[0].pos);
mulmtv(&obj[0].rot, &vc, &vc_c);
if (vc_c.z > 0.) {
proj(v2d, &vc_c);
return true;
}
return false;
}
}
if (pts2d[mod[obj[o].model].fac[mo][p].p[0]].xl!=MAXINT && pts2d[mod[obj[o].model].fac[mo][p].p[1]].xl!=MAXINT && pts2d[mod[obj[o].model].fac[mo][p].p[2]].xl!=MAXINT)
polyphong(
&pts2d[mod[obj[o].model].fac[mo][p].p[0]],
&pts2d[mod[obj[o].model].fac[mo][p].p[1]],
&pts2d[mod[obj[o].model].fac[mo][p].p[2]],
coul);
else
polyflat(
&pts2d[mod[obj[o].model].fac[mo][p].p[0]].v,
&pts2d[mod[obj[o].model].fac[mo][p].p[1]].v,
&pts2d[mod[obj[o].model].fac[mo][p].p[2]].v,
coul);
}
}
}
}
}
}
}
}
if (night_mode && obj[o].type==TYPE_LIGHT) { // HALO
plotphare(e.x,e.y,rayonapparent*4+1);
}
}
}
}
if (fast!=1) { o=obj[o].prec; no--; } else o=obj[o].next;
} while (o!=-1);
}
static bool to_camera(struct vector const *v3d, struct vect2d *v2d)
{
struct vector vc = *v3d;
struct vector vc_c;
subv(&vc, &obj[0].pos);
mulmtv(&obj[0].rot, &vc, &vc_c);
if (vc_c.z > 0.) {
proj(v2d, &vc_c);
return true;
}
return false;
}
Code:
void renderer(int ak, enum render_part fast) {
int o, p, no;
struct vector c,t,pts3d;
double rayonapparent=0;
struct matrix co;
struct vect2d e;
//obj[0]=light
if (map[ak].first_obj==-1) return;
// boucler sur tous les objets
for (o=map[ak].first_obj; o!=-1; o=obj[o].next) {
if ((fast==1 && obj[o].type!=TYPE_CLOUD) || fast==2) continue;
// calcul la position de l'objet dans le repère de la caméra, ie CamT*(objpos-campos)
// if (obj[o].model==0) continue; // une roue effacée
// copyv(&obj[o].t,&obj[o].pos);
subv3(&obj[o].pos,&obj[0].pos,&obj[o].t);
mulmtv(&obj[0].rot,&obj[o].t,&obj[o].posc);
obj[o].distance = norme2(&obj[o].posc);
}
// reclasser les objets en R2
if (fast==0 || fast==3) { // 1-> pas la peine et 2-> deja fait.
o=map[ak].first_obj;
if (obj[o].next!=-1) do { // le if est utile ssi il n'y a qu'un seul objet
int n=obj[o].next, ii=o;
//for (p=0; p!=-1; p=obj[p].next) printf("%d<",p);
//printf("\n");
while (ii!=-1 && obj[n].distance<obj[ii].distance) ii=obj[ii].prec;
if (ii!=o) { // réinsère
obj[o].next=obj[n].next;
if (obj[o].next!=-1) obj[obj[o].next].prec=o;
obj[n].prec=ii;
if (ii==-1) {
obj[n].next=map[ak].first_obj;
map[ak].first_obj=n;
obj[obj[n].next].prec=n;
} else {
obj[n].next=obj[ii].next;
obj[ii].next=n;
obj[obj[n].next].prec=n;
}
} else o=obj[o].next;
} while (o!=-1 && obj[o].next!=-1);
}
// affichage des ombres
o=map[ak].first_obj; no=0;
if (fast!=1) do {
float z;
char aff=norme2(&obj[o].t)<TILE_LEN*TILE_LEN*4;
if (obj[o].aff && (fast==3 || (fast==0 && (obj[o].type==TYPE_CAR || obj[o].type==TYPE_TANK || obj[o].type==TYPE_LIGHT || obj[o].type==TYPE_DECO || obj[o].type==TYPE_DEBRIS)) || (fast==2 && (obj[o].type==TYPE_PLANE || obj[o].type==TYPE_ZEPPELIN || obj[o].type==TYPE_INSTRUMENTS || obj[o].type==TYPE_BOMB)))) {
mulmt3(&oL[no], &obj[o].rot, &light);
#define DISTLUM 300.
mulv(&oL[no].x,DISTLUM);
mulv(&oL[no].y,DISTLUM);
if (aff && (z=z_ground(obj[o].pos.x,obj[o].pos.y, true))>obj[o].pos.z-500) {
for (p=0; p<mod[obj[o].model].nbpts[1]; p++) {
mulmv(&obj[o].rot, &mod[obj[o].model].pts[1][p], &pts3d);
addv(&pts3d,&obj[o].pos);
pts3d.x+=pts3d.z-z;
pts3d.z=z;
subv(&pts3d,&obj[0].pos);
mulmtv(&obj[0].rot,&pts3d,&pts3d);
if (pts3d.z >0) proj(&pts2d[p].v,&pts3d);
else pts2d[p].v.x = MAXINT;
}
for (p=0; p<mod[obj[o].model].nbfaces[1]; p++) {
if (scalaire(&mod[obj[o].model].fac[1][p].norm,&oL[no].z)<=0 &&
pts2d[mod[obj[o].model].fac[1][p].p[0]].v.x != MAXINT &&
pts2d[mod[obj[o].model].fac[1][p].p[1]].v.x != MAXINT &&
pts2d[mod[obj[o].model].fac[1][p].p[2]].v.x != MAXINT)
polyflat(
&pts2d[mod[obj[o].model].fac[1][p].p[0]].v,
&pts2d[mod[obj[o].model].fac[1][p].p[1]].v,
&pts2d[mod[obj[o].model].fac[1][p].p[2]].v,
(struct pixel){ .r = 0, .g = 0, .b = 0});
}
}
}
o=obj[o].next; no++;
} while (o!=-1);
if (no>MAXNO) printf("ERROR ! NO>MAXNO AT ak=%d (no=%d)\n",ak,no);
// affichage dans l'ordre du Z
o=map[ak].first_obj; no=0;
if (fast!=1) while (obj[o].next!=-1 /*&& (viewall || obj[obj[o].next].distance<TL2)*/) { o=obj[o].next; no++; }
do {
if (
fast==3 ||
(fast==1 && obj[o].type==TYPE_CLOUD) ||
(fast==0 && (obj[o].type==TYPE_CAR || obj[o].type==TYPE_TANK || obj[o].type==TYPE_LIGHT || obj[o].type==TYPE_DECO || obj[o].type==TYPE_DEBRIS)) ||
(fast==2 && (obj[o].type==TYPE_PLANE || obj[o].type==TYPE_ZEPPELIN || obj[o].type==TYPE_SMOKE || obj[o].type==TYPE_SHOT || obj[o].type==TYPE_BOMB || obj[o].type==TYPE_INSTRUMENTS || obj[o].type==TYPE_CLOUD))
) {
if (obj[o].aff && obj[o].posc.z>-mod[obj[o].model].rayon) { // il faut déjà que l'objet soit un peu devant la caméra et que ce soit pas un objet à passer...
int visu;
if (obj[o].posc.z > 0) {
// on va projetter ce centre à l'écran
proj(&e,&obj[o].posc);
rayonapparent = proj1(mod[obj[o].model].rayon,obj[o].posc.z);
visu = e.x>-rayonapparent && e.x<win_width+rayonapparent && e.y>-rayonapparent && e.y<win_height+rayonapparent;
} else { // verifier la formule qd meme...
if (obj[o].type != TYPE_CLOUD && obj[o].type != TYPE_SMOKE && obj[o].type != TYPE_LIGHT) {
double r = mod[obj[o].model].rayon*sqrt(z_near*z_near+win_center_x*win_center_x)/win_center_x;
visu = obj[o].posc.z > z_near*fabs(obj[o].posc.x)/win_center_x - r;
r = mod[obj[o].model].rayon*sqrt(z_near*z_near+win_center_y*win_center_y)/win_center_y;
visu = visu && (obj[o].posc.z > z_near*fabs(obj[o].posc.y)/win_center_y - r);
rayonapparent = win_width;
} else visu=0;
}
// la sphère est-elle visible ?
if (visu) {
if (obj[o].type == TYPE_CLOUD) {
if (night_mode) plotfumee(e.x,e.y,rayonapparent);
else plotnuage(e.x,e.y,rayonapparent);
}
else if (obj[o].type == TYPE_SMOKE) {
if (smoke_radius[o-smoke_start] > 0.) {
plotfumee(e.x, e.y, (int)(rayonapparent*smoke_radius[o-smoke_start]) >> 9);
}
} else {
if (rayonapparent>.3) {
if (rayonapparent<.5) plot(e.x-win_center_x,e.y-win_center_y,0x0);
else {
int mo = obj[o].distance<(TILE_LEN*TILE_LEN*.14) ? 0 : 1;
// on calcule alors la pos de la obj[0] dans le repère de l'objet, ie ObjT*(campos-objpos)
mulmtv(&obj[o].rot,&obj[o].t,&c);
neg(&c);
// on calcule aussi la position de tous les points de l'objet dans le repere de la camera, ie CamT*Obj*u
mulmt3(&co,&obj[0].rot,&obj[o].rot);
for (p=0; p<mod[obj[o].model].nbpts[mo]; p++) {
mulmv(&co, &mod[obj[o].model].pts[mo][p], &pts3d);
addv(&pts3d,&obj[o].posc);
if (pts3d.z>0) proj(&pts2d[p].v,&pts3d);
else pts2d[p].v.x = MAXINT;
// on calcule aussi les projs des
// norms dans le plan lumineux infiniment éloigné
if (scalaire(&mod[obj[o].model].norm[mo][p],&oL[no].z)<0) {
pts2d[p].xl = scalaire(&mod[obj[o].model].norm[mo][p],&oL[no].x);
pts2d[p].yl = scalaire(&mod[obj[o].model].norm[mo][p],&oL[no].y);
} else pts2d[p].xl = MAXINT;
}
if (obj[o].type==TYPE_SHOT) {
if (pts2d[0].v.x!=MAXINT && pts2d[1].v.x!=MAXINT) drawline(&pts2d[0].v, &pts2d[1].v, 0xFFA0F0);
} else {
for (p=0; p<mod[obj[o].model].nbfaces[mo]; p++) {
// test de visibilité entre obj[0] et normale
copyv(&t,&mod[obj[o].model].pts[mo][mod[obj[o].model].fac[mo][p].p[0]]);
subv(&t,&c);
if (scalaire(&t,&mod[obj[o].model].fac[mo][p].norm)<=0) {
if (pts2d[mod[obj[o].model].fac[mo][p].p[0]].v.x != MAXINT &&
pts2d[mod[obj[o].model].fac[mo][p].p[1]].v.x != MAXINT &&
pts2d[mod[obj[o].model].fac[mo][p].p[2]].v.x != MAXINT) {
if (obj[o].type==TYPE_INSTRUMENTS && p>=mod[obj[o].model].nbfaces[mo]-2) {
struct vect2dm pt[3];
int i;
for (i=0; i<3; i++) {
pt[i].v.x=pts2d[mod[obj[o].model].fac[mo][p].p[i]].v.x;
pt[i].v.y=pts2d[mod[obj[o].model].fac[mo][p].p[i]].v.y;
}
if (p-(mod[obj[o].model].nbfaces[mo]-2)) {
pt[2].mx=MAP_MARGIN;
pt[2].my=pannel_width+MAP_MARGIN;
pt[0].mx=pannel_height+MAP_MARGIN;
pt[0].my=MAP_MARGIN;
pt[1].mx=pannel_height+MAP_MARGIN;
pt[1].my=pannel_width+MAP_MARGIN;
} else {
pt[0].mx=MAP_MARGIN;
pt[0].my=pannel_width+MAP_MARGIN;
pt[1].mx=MAP_MARGIN;
pt[1].my=MAP_MARGIN;
pt[2].mx=pannel_height+MAP_MARGIN;
pt[2].my=MAP_MARGIN;
}
polymap(&pt[0],&pt[1],&pt[2]);
} else {
struct pixel coul = mod[obj[o].model].fac[mo][p].color;
if (night_mode) {
if (obj[o].type != TYPE_INSTRUMENTS) {
darken(&coul.r);
}
darken(&coul.g);
darken(&coul.
Code:
void polyphong(struct vect2dlum *p1, struct vect2dlum *p2, struct vect2dlum *p3, struct pixel coul) {
struct vect2dlum *tmp;
int xi, yi, lx, dx, dy, i, j, jlim, yfin;
int q1, q2, q3, ql, p1x, p1y, p2x, p2y, qx, qx2, ql2, px,py,px2,py2;
int a, aa, k, x, y, atmp, l;
struct pixel32 *vid;
if (p2->v.y<p1->v.y) { tmp=p1; p1=p2; p2=tmp; }
if (p3->v.y<p1->v.y) { tmp=p1; p1=p3; p3=tmp; }
if (p3->v.y<p2->v.y) { tmp=p2; p2=p3; p3=tmp; }
if (p1->v.y==p2->v.y && p1->v.x>p2->v.x) { tmp=p1; p1=p2; p2=tmp; }
if (p3->v.y<0 || p1->v.y>win_height) return;
// if (p1->v.y==p2->v.y) p1->v.y--; // de l'avantage d'une grosse rézo...
// if (p3->v.y==p2->v.y) p3->v.y++;
yi=p1->v.y; y=p1->yl<<vf;
if (p3->v.y==p1->v.y) {
if (p1->v.x>p3->v.x) { tmp=p1; p1=p3; p3=tmp; }
if (p2->v.x<p3->v.x) { tmp=p2; p2=p3; p3=tmp; }
xi = p1->v.x<<vf;
x=p1->xl<<vf;
lx = (p2->v.x - p1->v.x +1);
yfin = yi+1;
dx = ((p2->xl-p1->xl)<<vf)/lx;
dy = ((p2->yl-p1->yl)<<vf)/lx;
lx <<= vf;
a=(dx*dx+dy*dy)>>vf;
aa=a+a;
goto debtrace;
}
xi=p1->v.x<<vf;
x=p1->xl<<vf;
lx = 1<<vf;
q1=((p3->v.x-p1->v.x)<<vf)/(p3->v.y-p1->v.y);
p1x=((p3->xl-p1->xl)<<vf)/(p3->v.y-p1->v.y); // vecteurs quotients dans la "texture"
p1y=((p3->yl-p1->yl)<<vf)/(p3->v.y-p1->v.y);
if (p1->v.y!=p2->v.y) {
q2=((p2->v.x-p1->v.x)<<vf)/(p2->v.y-p1->v.y);
p2x=((p2->xl-p1->xl)<<vf)/(p2->v.y-p1->v.y);
p2y=((p2->yl-p1->yl)<<vf)/(p2->v.y-p1->v.y);
} else {
q2 = p2x = p2y = MAXINT;
lx = (p2->v.x-p1->v.x+1)<<vf;
}
if (p3->v.y!=p2->v.y) {
q3=((p3->v.x-p2->v.x)<<vf)/(p3->v.y-p2->v.y);
} else {
q3 = MAXINT;
}
if (q1<=q2) {
int p3x,p3y;
ql = (q2-q1)|1; // le taux d'accroissement de la taille du segment (en évitant 0);
ql2= (q3-q1)|1;
qx=qx2=q1;
if (q2==MAXINT && p3->v.y!=p2->v.y) {
p3x=((p3->xl-p2->xl)<<vf)/(p3->v.y-p2->v.y);
p3y=((p3->yl-p2->yl)<<vf)/(p3->v.y-p2->v.y);
dx=((p3x-p1x)<<vf)/ql2;
dy=((p3y-p1y)<<vf)/ql2;
} else {
dx=((p2x-p1x)<<vf)/ql;
dy=((p2y-p1y)<<vf)/ql;
}
px=px2=p1x; py=py2=p1y;
} else {
int p3x,p3y;
ql = (q1-q2)|1;
ql2= q1-q3;
qx=q2; qx2=q3;
dx=((p1x-p2x)<<vf)/ql;
dy=((p1y-p2y)<<vf)/ql;
if (p3->v.y!=p2->v.y) {
p3x=((p3->xl-p2->xl)<<vf)/(p3->v.y-p2->v.y);
p3y=((p3->yl-p2->yl)<<vf)/(p3->v.y-p2->v.y);
} else {
p3x = p3y = 0;
}
px=p2x; px2=p3x; py=p2y; py2=p3y;
}
a=(dx*dx+dy*dy)>>vf;
aa=a+a;
// clipper les y<0 ! sinon ca fait des pauses !
yfin=p2->v.y;
if (p2->v.y<0) {
xi+=(p2->v.y-p1->v.y)*qx;
yi=p2->v.y;
lx+=(p2->v.y-p1->v.y)*ql;
x+=(p2->v.y-p1->v.y)*px; y+=(p2->v.y-p1->v.y)*py;
yfin=p3->v.y; ql=ql2; qx=qx2; px=px2; py=py2;
}
if (yi<0) {
xi-=yi*qx;
lx-=yi*ql;
x-=yi*px; y-=yi*py;
yi=0;
}
debtrace:
vid=videobuffer+(yi)*win_width;
for (i=0; i<2; i++, yfin=p3->v.y, ql=ql2, qx=qx2, px=px2, py=py2){
while (yi<yfin && yi<win_height) {
k=(dx*(x>>vf)+dy*(y>>vf))<<1;
l=x*(x>>vf)+y*(y>>vf);
atmp=a;
jlim=(lx+xi)>>vf;
j=xi>>vf;
if (j<0) {
l += -j*(k+atmp+(((-j-1)*aa)>>1));
atmp += -j*aa;
j=0;
}
if (jlim>win_width-1) jlim=win_width-1;
if (j<jlim) {
for (; j!=jlim; j++) {
unsigned const cc = l <= 0 ? MAX_PRECA : l >= (1<<24) ? 0 : preca[l>>16];
vid[j].r = add_sat(coul.r, cc, 255);
vid[j].g = add_sat(coul.g, cc, 255);
vid[j].b = add_sat(coul.b, cc, 255);
l += k + atmp;
atmp += aa;
}
}
xi+=qx; yi++;
lx+=ql;
x+=px; y+=py;
vid+=win_width;
}
}
}
Code:
void nxtrt(struct vector i, struct vector *f, int lastd) {
// routeidx pointe sur une route dont l'origine est mise, mais
// pointant sur rien
int d, bestd=0, intens;
float bestnote=MAXFLOAT, notecur, dist, s;
struct pixel coul;
struct vector r,besta,u;
float tmp;
copyv(&r,f);
subv(&r,&i);
dist=norme(&r);
if (NbElmLim<0 || dist<TILE_LEN || routeidx>=NBMAXROUTE-1) {
routeidx++;
route[routeidx].ak=-1; // mark fin de route
routeidx++;
return;
}
NbElmLim--;
akref(route[routeidx].ak,&r);
// printf("nxtrt: ak=%d akref=%f %f i=%f %f\n",route[routeidx].ak,r.x,r.y,route[routeidx].i.x,route[routeidx].i.y);
// printf("nxtrt : from %f %f - dist=%f\n",i.x,i.y,dist);
for (d=0; d<4; d++) {
// d=coté parcouru : 0=sud, 1=ouest, 2=nord, 3=ouest
if (d==(lastd^2)) continue;
for (s=TILE_LEN/5; s<TILE_LEN*4/5; s+=TILE_LEN/10) {
float ll=d>1?TILE_LEN:0;
struct vector a;
a.x=(d&1?ll:s)+r.x;
a.y=(d&1?s:ll)+r.y;
a.z=z_ground(a.x,a.y, false);
if ((notecur=note(&a,f,&i))<bestnote) {
bestnote=notecur;
bestd=d;
copyv(&besta,&a);
bestcap=curcap;
}
}
}
if (bestnote>1000) {
route[routeidx].ak=-1;
routeidx++;
return;
}
oldcap=bestcap;
// printf(" found this way : dir=%d, leading to %f %f (note=%f)\n",bestd, besta.x,besta.y,bestnote);
routeidx++;
copyv(&route[routeidx].i,&besta);
subv3(&route[routeidx-1].i,&route[routeidx].i,&u);
tmp=u.x; u.x=u.y; u.y=-tmp; u.z=0;
renorme(&u);
mulv(&u,largroute[actutype]);
addv3(&route[routeidx].i,&u,&route[routeidx].i2);
route[routeidx].ak=route[routeidx-1].ak;
*((int*)&route[routeidx-1].e.c)=0x4A6964; // couleur par défaut
switch (bestd) {
case 0:
route[routeidx].ak-=MAP_LEN;
d=route[routeidx].ak<MAP_LEN;
break;
case 1:
route[routeidx].ak-=2;
case 3:
route[routeidx].ak+=1;
d=(route[routeidx].ak&MAP_LEN)!=(route[routeidx-1].ak&MAP_LEN);
break;
case 2:
route[routeidx].ak+=MAP_LEN;
d=route[routeidx].ak>=MAP_LEN<<(LOG_MAP_LEN-1);
break;
}
if (d) {
// printf("Interrputing road\n");
route[routeidx].ak=-1;
routeidx++;
return;
}
// colore la route
intens=((map[route[routeidx].ak].z-map[(route[routeidx].ak-1)&((MAP_LEN<<LOG_MAP_LEN)-1)].z))+32+64;
if (intens<80) intens=80;
else if (intens>117) intens=117;
if (EndMotorways==-1) {coul.r=120; coul.g=150; coul.b=130; }
else if (EndRoads==-1) {coul.r=90; coul.g=130; coul.b=110; }
else { coul.r=100; coul.g=120; coul.b=70; }
route[routeidx-1].e.c.r=(coul.r*intens)>>7;
route[routeidx-1].e.c.g=(coul.g*intens)>>7;
route[routeidx-1].e.c.b=(coul.b*intens)>>7;
if (route[routeidx-1].e.c.r<20) route[routeidx-1].e.c.r=20; // pour éviter les swaps
if (route[routeidx-1].e.c.g<20) route[routeidx-1].e.c.g=20;
if (route[routeidx-1].e.c.b<20) route[routeidx-1].e.c.b=20;
// avance le chantier
akref(route[routeidx].ak,&r);
nxtrt(besta,f,bestd);
}
roads.c:243:
Code:
void prospectroute(struct vector *i, struct vector *f) {
int deb=routeidx, bestfin=MAXINT;
int j,k;
int nbelmlim; // nb d'element au dela duquel ca vaut pas le coup
struct vector p1,p2, bestp1, bestp2, v;
copyv(&p1,i);
copyv(&p2,f);
copyv(&v,f);
subv(&v,i);
nbelmlim=8.*norme(&v)/TILE_LEN;
if (EndMotorways==-1) actutype=0;
else if (EndRoads==-1) actutype=1;
else actutype=2;
for (j=0; j<10; j++) {
if (j) {
randomv(&v);
mulv(&v,TILE_LEN*(EndRoads==-1?2:0.00001));
addv(&p1,&v);
p1.z=z_ground(p1.x,p1.y, false);
randomv(&v);
mulv(&v,TILE_LEN*(EndRoads==-1?2:3));
addv(&p2,&v);
p2.z=z_ground(p2.x,p2.y, false);
}
NbElmLim=nbelmlim;
traceroute(&p1,&p2);
k=routeidx-2;
if (k>=0) {
// akref(route[k].ak,&v);
v = route[k].i;
subv(&v, f);
if (
routeidx < bestfin &&
norme(&v) < 2.*TILE_LEN
) {
bestp1 = p1;
bestp2 = p2;
bestfin = routeidx;
}
}
routeidx=deb;
}
if (bestfin-routeidx<nbelmlim) {
NbElmLim=nbelmlim;
traceroute(&bestp1,&bestp2);
}
}
Code:
int present(void)
{
int curround = 0, oldcurround, nextround, etap = 2;
float phaz = drand48()*2*M_PI;
float phazr = drand48()*2*M_PI;
float radius = 2.;
float rot_speed = 40.;
gtime_start();
do {
float const dt_sec = gtime_next_sec();
if (etap==1) { // explose
radius += 9.*dt_sec;
if (radius > 1.5) {
if (nextround<0) {
switch (nextround) {
case -1: return -1;
case -2: return 1;
case -4: NBBOT=jauge(NBBOT,100); break;
case -5: NBTANKBOTS=jauge(NBTANKBOTS,500); break;
case -7: CtlSensitiv=.01*jauge(100*CtlSensitiv,100); break;
case -8: CtlAmortis=.01*jauge(100*CtlAmortis,100); break;
case -6: redefinekeys(); break;
/* case -9: readstring(hostname);
case -10: readstring(myname);*/
case -11: hilly_level=300+exp(.1*jauge(log(hilly_level-300.)/.1,100)); break;
case -12: smooth_level=2+jauge(smooth_level-2,20); break;
}
} else curround=nextround;
etap=2;
}
} else if (etap==2) { // implose
radius -= dt_sec * 2.2;
if (radius <= .4) {
etap = 0;
radius = .4;
}
}
kzc = kazeclick(xmouse, ymouse, curround);
draw_page(curround, radius + .018*sin(phazr), phaz);
plotcursor(xmouse, ymouse);
buffer2video();
xproceed();
phaz += rot_speed * dt_sec * (.13 + sin(phazr*1.1)*.61);
phazr += rot_speed * dt_sec * (sin(phaz*.312)*.63 + sin(phazr*.13)*.31);
rot_speed *= pow(0.1, dt_sec);
if (etap==0 && (button_reset(SDL_BUTTON_LEFT) || button_reset(SDL_BUTTON_RIGHT))) {
if (kzc != -1) {
rot_speed = 40.;
phaz = drand48()*2*M_PI;
phazr = drand48()*2*M_PI;
struct vector mousepos = { .x = (float)xmouse/win_width, .y = (float)ymouse/win_height, .z = 0. };
playsound(VOICE_MOTOR, SAMPLE_BIPINTRO, 1+(drand48()-.5)*.05, &mousepos, true, false);
bg_shaking = 50*256;
if (Round[curround].kase[kzc].nxtround>=0) {
oldcurround=curround;
nextround=Round[curround].kase[kzc].nxtround;
etap=1;
} else {
switch (Round[curround].kase[kzc].nxtround) {
case -1: etap=1; nextround=-2; break;
case -2: etap=1; nextround=-6; break;
case -3: etap=1; nextround=-1; break;
case -4: etap=1; nextround=-4; break;
case -5: etap=1; nextround=-5; break;
case -6: enable_resurrection=0; break;
case -7: etap=1; nextround=-7; break;
case -8: etap=1; nextround=-8; break;
/* case -9: etap=1; nextround=-9; break;
case -10: etap=1; nextround=-10; break;*/
case -11: easy_mode=1; break;
case -12: easy_mode=0; break;
case -13: enable_view_enemy=1; break;
case -14: killemall_mode=0; break;
case -15: killemall_mode=1; break;
case -16: starting_plane=1; break;
case -17: starting_plane=4; break;
case -18: starting_plane=2; break;
case -19: starting_plane=3; break;
case -20: camp=0; break;
case -21: camp=1; break;
case -22: camp=2; break;
case -23: camp=3; break;
case -24: night_mode=0; break;
case -25: night_mode=1; break;
case -26: enable_mouse=1; break;
case -27: enable_mouse=0; break;
case -28: lang=1; break;
case -29: lang=0; break;
case -30: enable_view_enemy=0; break;
case -31: cheat_mode=1; break;
case -32: cheat_mode=0; break;
case -33: enable_resurrection=1; break;
case -34: starting_plane=5; break;
case -35: etap=1; nextround=-11; break;
case -36: etap=1; nextround=-12; break;
case -37: starting_plane=6; break;
}
if (etap==0) {
nextround=oldcurround;
etap=1;
}
}
}
}
} while (! quit_game);
return -1;
}
Last edited by a moderator: