Voilà, j'avais voulu me remettre à F-Zero ce soir, mais en essayant de recompiler (avec GCC sur PC), je me rends compte que ça marche plus ; et j'ai bien l'impression que ça vient d'un bug de ma version de GCC...
Mettez ça dans bug.c :
#define vs_tile 8
#define vs_ntiles 42
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
extern int vs_xpos,vs_ypos;
extern const int vs_diff_corner[12];
extern const int vs_diff_line[12];
u8 *pixels;
int w,h;
typedef u8 vs_line[256];
vs_line _vscreen[256];
#define vscreen (_vscreen+128)
#ifndef nkop
extern int nkop;
#endif
void Mode7_UpdateVscreen(u32 xpos,u32 ypos) {
#if vs_tile==8
#define _put_tile(fx,fy) \
do { \
u32 *src = (u32 *)&((u8 *)pixels)[ \
(n_ypos+(y^fy))*vs_tile*w+(n_xpos+(x^fx))*vs_tile \
]; \
u32 *dst = (u32 *)&vscreen[(s8)((nkop+n_ypos+(y^fy))*vs_tile)][(u8)((n_xpos+(x^fx))*vs_tile)]; \
for (int n=8;n--;src+=w/4,dst+=256/4) \
dst[0]=src[0], dst[1]=src[1]; \
} while (0)
#endif
int x,y;
xpos>>=16; ypos>>=16;
u16 n_xpos = (u32)(xpos+vs_tile/2)/vs_tile - vs_ntiles/2,
n_ypos = (u32)(ypos+vs_tile/2)/vs_tile - vs_ntiles/2;
s16 dx = n_xpos-vs_xpos, dy = n_ypos-vs_ypos;
vs_xpos = n_xpos, vs_ypos = n_ypos;
s16 fx = 0, fy = 0;
if (dx>0)
dx=-dx, fx=vs_ntiles-1;
if (dy>0)
dy=-dy, fy=vs_ntiles-1;
dx=dy=42;
if (dx==-1 && dy==-1) {
const int *diff_ptr = vs_diff_corner;
int n = 25; // number of lines in vs_diff_corner
y = 0;
while (n--) {
while ((x = *diff_ptr++)>=0)
_put_tile(fx,fy);
y++;
}
} else if (!dx && dy==-1) {
const int *diff_ptr = vs_diff_line;
for (x=0;x<vs_ntiles;x++) {
y = *diff_ptr++;
_put_tile(0,fy);
}
} else if (dx==-1 && !dy) {
const int *diff_ptr = vs_diff_line;
for (y=0;y<vs_ntiles;y++) {
x = *diff_ptr++;
_put_tile(fx,0);
}
} else if (dx || dy)
for (y=0;y<vs_ntiles;y++)
for (x=0;x<vs_ntiles;x++)
_put_tile(0,0);
#undef _put_tile
}
puis dites-moi si vous voyez une différence entre le code généré par
gcc -O2 --std=c99 -S bug.c
et
gcc -O2 --std=c99 -Dnkop=0 -S bug.c
Dans les deux cas j'ai bien l'impression que c'est le même code buggé, alors que si on fait
gcc -O2 --std=c99 -Dnkop=42 -S bug.c
ou à peu près n'importe quelle valeur non nulle à la place de 42 le code est, cette fois-ci, correct... (et donc différent)
PS : pour les curieux, gcc --version me renvoie "gcc (GCC) 3.3.3 (cygwin special)"