attempting to port Fachoda-Complex, ground clipping issues?


TrashyMG

Sarcasm Dispenser
Staff member
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..



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 &#224; part !


    if (p1->y!=p2->y) {


        q2=((p2->x-p1->x)<<vf)/(p2->y-p1->y);


    } else {    // on a forc&#233;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 &#233;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;


}

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&#232;re de la cam&#233;ra, ie CamT*(objpos-campos)


//      if (obj[o].model==0) continue;  // une roue effac&#233;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&#233;ins&#232;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&#233;j&#224; que l'objet soit un peu devant la cam&#233;ra et que ce soit pas un objet &#224; passer...


                int visu;


                if (obj[o].posc.z > 0) {


                    // on va projetter ce centre &#224; l'&#233;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&#232;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&#232;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 &#233;loign&#233;


                                    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&#233; 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&#233;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 &#233;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&#233; 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&#233;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 &#233;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:
I dont know about the code, but conversion from float to integer for collision detection can yield problems such as falling through inbetween polygon edges and other inaccuracy problems depending on what system is used to calculate collisions. If collisons are wrong its probably a loss of precision somewere.
 
I dont know about the code, but conversion from float to integer for collision detection can yield problems such as falling through inbetween polygon edges and other inaccuracy problems depending on what system is used to calculate collisions. If collisons are wrong its probably a loss of precision somewere.

It's what I was suspecting as well. I'm just not sure what to do about it.
 
Hi!


At first sight, it seams your binary of fachoda complex is not fast enough. The simulation steps (including collision detection) is done at every


frame, so if the frame rate is too low the ground collision detection happens too late, the plane being already far under the ground and thus bounce quite high.


Sorry for such a lame ground collision technique (and such an awful code overall).


Also, I recently compiled the game on my n900 and fixed a few errors preventing the game to behave as expected (like chars that were assumed to be signed). So be sure to follow master on github.
 
Wow thanks Rixed for the info.. I overclocked the Pandora a bit to 1000mhz and seemed to improve.. although not fully. I'll keep an eye for updates on your github page.


Edit: I managed to get a plane off the ground!


Edit: 1000mhz seems to be the lowest speed needed to clear up this issue.. putting it out of the range of some Pandoras that can't overclock that fast.. I compiled using neon, I'm not sure were else I could optimize to speed up the binary. I am pretty new to ARM compiling issues, so I may need some educating.
 
Last edited by a moderator:
Edit: 1000mhz seems to be the lowest speed needed to clear up this issue.. putting it out of the range of some Pandoras that can't overclock that fast.. I compiled using neon, I'm not sure were else I could optimize to speed up the binary. I am pretty new to ARM compiling issues, so I may need some educating.

I'm surprised you have so much speed issues on the openpandora since on the N900 (a similar hardware AFAIK) the speed is good enough.


Do you compile with -ffast-math, -fomit-frame-pointer and of course -O3 ?


Also, what screen resolution do you use ?


The GlES version will not come before long since there are many shadders to write first (phong, bumpmap for the instrument pannel, fonts...)
 
I've used -ffast-math and -O3.. haven't tried -fomit-frame-pointer


Edit: also the Pandora has an 800x480 resolution screen what I have been setting it to. I suppose I could tweak it down.
 
Last edited by a moderator:
Edit: also the Pandora has an 800x480 resolution screen what I have been setting it to. I suppose I could tweak it down.

Ok, that's probably the problem. If you lower the resolution (for instance, 400x240!) will the pandora zoom it in fullscreen mode? That would be ideal.
 
Edit: also the Pandora has an 800x480 resolution screen what I have been setting it to. I suppose I could tweak it down.

Ok, that's probably the problem. If you lower the resolution (for instance, 400x240!) will the pandora zoom it in fullscreen mode? That would be ideal.

You can easily use notaz SDL for that ;)
 
Just did a quick test 400x240 seems promising, seems to work fine at 800mhz now.. I may still fiddle with compiling optimization, been reading a lot about it.. some say I may get more speed with using -O2 and using select optimizations vs -O3.. but who knows..


Yeah I need to look into using Notaz's SDL, It seems pretty straight forward.. You think that may give any performance boosts?


I still need to make the default controls more Pandora friendly, but that shouldn't take too long and then I can push a PND to the public. I just need to free myself from work and Mass Effect 3...
 
Last edited by a moderator:
Well I got the game performing great with Notaz's SDL it's fullscreen and fully playable at 500mhz, I set the default to 600mhz to be safe.. But one new problem, This seemed to break mouse mode on the nubs and it no longer works in game.. Is it getting set to joystick mode by default? I didn't see any environment variable that would toggle this in the readme for Notaz's SDL..
 
Last edited by a moderator:
Well I got the game performing great with Notaz's SDL it's fullscreen and fully playable at 500mhz, I set the default to 600mhz to be safe.. But one new problem, This seemed to break mouse mode on the nubs no longer works!? Is it getting set to joystick mode by default? I didn't see any environment variable that would toggle this in the readme for Notaz's SDL..

mouse does not work by design with notaz sdl
 
Well I got the game performing great with Notaz's SDL it's fullscreen and fully playable at 500mhz, I set the default to 600mhz to be safe.. But one new problem, This seemed to break mouse mode on the nubs no longer works!? Is it getting set to joystick mode by default? I didn't see any environment variable that would toggle this in the readme for Notaz's SDL..

mouse does not work by design with notaz sdl

ah sad times.. I mean D-pad control isn't bad with the game.. but analog control would of been key.. Perhaps I can hack in some joystick control.. I don't believe the game supports it at the moment.
 
Last edited by a moderator:
Back
Top