// En "crt" ficaré el "pegamento" amb SDL i les coses de Pascal // que vullga mantindre, com els noms dels tipos. #include "crt.h" // Amb "keybord.pas" faré el mateix, el convertiré a SDL, mantenint // la mateixa interficie #include "keyboard.h" // ================================================================= // CONST // ================================================================= // He decidit ficar defines per a les constants, que es el més // paregut. La constant "velocitat" se pegaba amb algunes variables // així que la he renombrat "velocitat_inicial" #define marge_dalt 20 #define marge_baix 460 #define marge_esq 20 #define marge_dret 620 #define max_ipunts 30 #define max_ornis 15 #define velocitat_inicial 2 #define velocitat_max 6 #define max_bales 3 // ================================================================= // TYPE // ================================================================= // Els tipos son structs normals. El ivector el tracte a part. struct ipunt { real r, angle; }; struct punt { integer x, y; }; // ivector es un simple array estatic de ipunts // typedef ipunt[max_ipunts] ivector; struct triangle { ipunt p1,p2,p3; punt centre; real angle; real velocitat; }; struct poligon { ipunt ipuntx[max_ipunts]; punt centre; real angle; real velocitat; byte n; real drotacio, rotacio; boolean esta; }; // NOTA1: // pvirt es un array estatic pa definir un punter que despres // pillem memoria dinamica... que mareig. Si total, es la pantalla // virtual que pillem la memoria i no la soltem en tot el joc. // Així que millor un simple array estatic i menys feina //pvirt=array [1..38400] of byte; // ================================================================= // VAR // ================================================================= // Ací han d'anar les variables globals. He llevat moltes perque nomes s'usen // dins del main, les quals son locals a main triangle nau; //poligon pol; //real ang; //char ch; //word Dx, Dy; //byte i, aux; //integer dist; //punt puntaux; //poligon orni[max_ornis]; byte virt[38400]; //poligon bales[max_bales]; // NOTA2: // Durant el joc se usa "mem" per a accedir a la memòria directament // per a escriure a la memòria de video (mem[$A000:i]) o a/desde la // memòria de la pantalla virtual (mem[sef(virt^):i]), lo qual es // marejador i ara ja no val per a res. Podria fingir-ho, pero seria // un desperdici de memòria. Així que vaig a intercanviar tot els // accesos a memoria de video per un access al array "video[]" i tots // els accesos a la pantalla virtual per acces al array "virt[]". // video[] està definit en "crt.h" void volca() { for (int i=0;i<38400;++i) video[i] = virt[i]; } void crear_poligon_regular(poligon &pol, byte n, real r) { real act, interval; ipunt aux; interval = 2*pi/n; act = 0; for (int i=0;i>3)] = (virt[y*80+(x>>3)] & 0x7F) | 0x80; break; case 1: virt[y*80+(x>>3)] = (virt[y*80+(x>>3)] & 0xBF) | 0x40; break; case 2: virt[y*80+(x>>3)] = (virt[y*80+(x>>3)] & 0xDF) | 0x20; break; case 3: virt[y*80+(x>>3)] = (virt[y*80+(x>>3)] & 0xEF) | 0x10; break; case 4: virt[y*80+(x>>3)] = (virt[y*80+(x>>3)] & 0xF7) | 0x08; break; case 5: virt[y*80+(x>>3)] = (virt[y*80+(x>>3)] & 0xFB) | 0x04; break; case 6: virt[y*80+(x>>3)] = (virt[y*80+(x>>3)] & 0xFD) | 0x02; break; case 7: virt[y*80+(x>>3)] = (virt[y*80+(x>>3)] & 0xFE) | 0x01; break; } } else if (color==0) { switch (x % 8) { case 0: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0x7F; break; case 1: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0xBF; break; case 2: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0xDF; break; case 3: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0xEF; break; case 4: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0xF7; break; case 5: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0xFB; break; case 6: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0xFD; break; case 7: virt[y*80+(x>>3)] = virt[y*80+(x>>3)] & 0xFE; break; } } } byte llig(word x, word y) { switch (x % 8) { case 0: return (virt[y*80+(x>>3)] & 0x80) >> 7; break; case 1: return (virt[y*80+(x>>3)] & 0x40) >> 6; break; case 2: return (virt[y*80+(x>>3)] & 0x20) >> 5; break; case 3: return (virt[y*80+(x>>3)] & 0x10) >> 4; break; case 4: return (virt[y*80+(x>>3)] & 0x08) >> 3; break; case 5: return (virt[y*80+(x>>3)] & 0x04) >> 2; break; case 6: return (virt[y*80+(x>>3)] & 0x02) >> 1; break; case 7: return virt[y*80+(x>>3)] & 0x01; break; } return 0; } void posavga(word x, word y, byte color) { if (color==1) { switch (x % 8) { case 0: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0x7F) | 0x80; break; case 1: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0xBF) | 0x40; break; case 2: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0xDF) | 0x20; break; case 3: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0xEF) | 0x10; break; case 4: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0xF7) | 0x08; break; case 5: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0xFB) | 0x04; break; case 6: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0xFD) | 0x02; break; case 7: video[y*80+(x>>3)] = (video[y*80+(x>>3)] & 0xFE) | 0x01; break; } } else if (color==0) { switch (x % 8) { case 0: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0x7F; break; case 1: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0xBF; break; case 2: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0xDF; break; case 3: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0xEF; break; case 4: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0xF7; break; case 5: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0xFB; break; case 6: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0xFD; break; case 7: video[y*80+(x>>3)] = video[y*80+(x>>3)] & 0xFE; break; } } } real modul(punt p) { // sqr(p.x) es p.x al quadrat, que sería p.x^2. Pero es mes rapid p.x*p.x return sqrt(p.x*p.x + p.y*p.y); } void diferencia(punt o, punt d, punt &p) { p.x = o.x-d.x; p.y = o.y-d.y; } integer distancia(punt o, punt d) { punt p; diferencia(o,d,p); return round(modul(p)); } real angle(punt p) { // p.x/p.y peta si p.y es zero, obviament, així que si es zero, canviem la operació // per un nombre proper a zero (0.001). return p.y!=0?atan(p.x/p.y):atan(p.x/0.001); } void clsvirt() { for (int i=0;i<38400;++i) virt[i]=0; } integer sign(integer x) { //like sgn(x) in basic // PASCAL: // if x<0 then sign:=-1 else if x>0 then sign:=1 else sign:=0 end; // C: // if (x<0) return -1; else if (x>0) return 1; else return 0; // DOC: return x<0?-1:x>0?1:0; } boolean linea(word x1, word y1, word x2, word y2, word color) { bool result = false; integer count; integer col = 0; integer x = x1, y = y1; integer xs = x2-x1, ys = y2-y1; integer xm = sign(xs), ym = sign(ys); xs = fabs(xs); ys = fabs(ys); if (llig(x,y)==1) col++; posa(x,y,color); if (xs > ys) { // flat line <45 deg count = -(xs >> 1); while (x != x2) { count += ys; x += xm; if (count>0) { y += ym; count -= xs; } if (llig(x,y)==1) col++; posa(x,y,color); } } else { // steep line >=45 deg count = -(ys >> 1); while (y != y2) { count += xs; y += ym; if (count>0) { x += xm; count -= ys; } if (llig(x,y)==1) col++; posa(x,y,color); } } if (col>2) result = true; return result; } byte rota_tri(triangle tri, real angul, real velocitat, byte color) { word x1 = round((tri.p1.r+velocitat)*cos(tri.p1.angle+angul))+tri.centre.x; word x2 = round((tri.p2.r+velocitat)*cos(tri.p2.angle+angul))+tri.centre.x; word x3 = round((tri.p3.r+velocitat)*cos(tri.p3.angle+angul))+tri.centre.x; word y1 = round((tri.p1.r+velocitat)*sin(tri.p1.angle+angul))+tri.centre.y; word y2 = round((tri.p2.r+velocitat)*sin(tri.p2.angle+angul))+tri.centre.y; word y3 = round((tri.p3.r+velocitat)*sin(tri.p3.angle+angul))+tri.centre.y; bool result = 0; if (linea(x1,y1,x2,y2,color)) result = 1; if (linea(x1,y1,x3,y3,color)) result = 1; if (linea(x3,y3,x2,y2,color)) result = 1; return result; } void rota_pol(poligon pol, real angul, byte color) { punt xy[max_ipunts]; for (int i=0;imarge_dalt) && (dymarge_esq) && (dxmarge_dalt) && (dymarge_esq) && (dx1) && (nau.p2.r>1) && (nau.p3.r>1) && (itocado<170)) { nau.p1.r = nau.p1.r-0.7; nau.p2.r = nau.p2.r-0.7; nau.p3.r = nau.p3.r-0.7; nau.angle = nau.angle-0.3; rota_tri(nau,nau.angle,0,1); } else { for (int i=0;i=0)&&(dx<640)&&(dy>0)&&(dy<480)) posa(dx,dy,1); } } itocado++; if (itocado==170) { nau.p1.r = 12; nau.p1.angle = 3*pi/2; nau.p2.r = 12; nau.p2.angle = pi/4; nau.p3.r = 12; nau.p3.angle = (3*pi)/4; nau.angle = 0; nau.centre.x = 320; nau.centre.y = 240; } if ((itocado>170)&&((itocado%3)==0)) rota_tri(nau,nau.angle,nau.velocitat,1); if (itocado>250) itocado=0; } int main(int argc, char *argv[]) { poligon pol; byte i, aux; poligon orni[max_ornis]; poligon bales[max_bales]; randomize(); //getmem(virt,38400); virt es un array estatic, no fa falta reservar memòria itocado = 0; clsvirt(); nau.p1.r = 12; nau.p1.angle = 3*pi/2; nau.p2.r = 12; nau.p2.angle = pi/4; nau.p3.r = 12; nau.p3.angle = (3*pi)/4; nau.angle = 0; nau.centre.x = 320; nau.centre.y = 240; crear_poligon_regular(pol, 10, 200); for (int i=1;imarge_dalt) && (dymarge_esq) && (dx0.1) nau.velocitat -= 0.1; /* dist:=distancia(nau.centre,pol.centre); diferencia(pol.centre,nau.centre,puntaux); if dist<(pol.ipuntx[1].r+30) then begin nau.centre.x:=nau.centre.x +round(dist*cos(angle(puntaux)+0.031415)); nau.centre.y:=nau.centre.y +round(dist*sin(angle(puntaux)+0.031415)); end;*/ /* for i:=1 to 5 do begin rota_pol(orni[i],ang,0); end;*/ for (int i=1;i