From 2936a401a190bb8fc7167d80be49aecd3c83595b052c3032826f8435d730a844 Mon Sep 17 00:00:00 2001 From: Gabriel Lorenzo Date: Thu, 24 Oct 2002 21:59:17 +0000 Subject: [PATCH] collision y timer --- ediv/CHANGE_LOG.txt | 9 + ediv/bin/ROBOTS.PRG | 318 +++++++++++++++++++++++++ ediv/ideQT/main.cpp | 3 + ediv/src/dlls/dlls.suo | Bin 20480 -> 21504 bytes ediv/src/dlls/edivstd/edivstd.c | 37 ++- ediv/src/dlls/export.h | 1 + ediv/src/dlls/graphics/graphics.vcproj | 1 + ediv/src/dlls/graphics/main.c | 94 ++++++-- ediv/src/dlls/math/math.c | 1 + ediv/src/shared/extern.h | 1 + ediv/src/stub/inte.c | 6 +- ediv/src/stub/stub.c | 2 +- ediv/src/visual c/ediv_ws.suo | Bin 32256 -> 22528 bytes 13 files changed, 444 insertions(+), 29 deletions(-) create mode 100644 ediv/bin/ROBOTS.PRG diff --git a/ediv/CHANGE_LOG.txt b/ediv/CHANGE_LOG.txt index 2dc108b..1e66d37 100644 --- a/ediv/CHANGE_LOG.txt +++ b/ediv/CHANGE_LOG.txt @@ -1,3 +1,12 @@ +24/10/2002 +---------- + * Ahora los id's de los procesos son siempre impares. (Er_Makina) + * Arreglado collision. He sustituido el algoritmo de choque entre dos cajas, + aunque no hacía falta, pero quizás así queda un poco más limpio. (Er_Makina) + * Añadido timer[], pero sólo en Win32. Hay que adaptarlo a Linux. (Er_Makina) + * tutor0b ya rula.. el robots asesinos ya parece que rula bien pero no puedo + mover al personaje, no se por qué... fallo en la input? (Er_Makina) + 21/10/2002 ---------- * delete_text() daba un runtime error si no existia el texto a eliminar. en diff --git a/ediv/bin/ROBOTS.PRG b/ediv/bin/ROBOTS.PRG new file mode 100644 index 0000000..bb4c43b --- /dev/null +++ b/ediv/bin/ROBOTS.PRG @@ -0,0 +1,318 @@ +/********************* + Los Robots Asesinos + ********************* + + (c) Er_Makina, 2000 + + www.sferasoft.org + + ******************** + Este programa es SOFTWARE LIBRE y puedes hacer con él + lo de te salga de las narices. Puedes modificarlo y + redistribuirlo libremente sin necesidad de notificar- + me nada. + ******************** + NOTAS: + - El programa funcionará bajo DIV 1 si se quita la 1ª + línea del programa (compiler_options) + - Para ejecutar el EXE, es necesario el archivo + DIV32RUN.DLL que podrás encontrar en la web oficial + de DIV (www.divgames.com) + ********************/ + +COMPILER_OPTIONS _extended_conditions; + +Program Juego_robots; +CONST + max_robots=25; + +GLOBAL + prota; + num_robots=5; + robots[max_robots]; + muerto[max_robots]; + muertos; + cogido; + ya; + +LOCAL + i; + +PRIVATE + protax; + protay; + mueve; + harf; + j; + espe; + +BEGIN + load_fpg("robots.fpg"); + load_fnt("system.fnt"); + write(1,0,0,0,"Pulsa F1 para obtener ayuda"); + write(1,160,100,4,"¨PREPARADO?"); + espe=1; + mouse.flags=4; + loop +// fade_on(); + prota=protag(rand(0,39)*8,rand(0,24)*8); + for(i=1;i<=num_robots;i++) + loop + x=rand(0,39); + y=rand(0,24); + graph=2; + if(fget_dist(x,y,prota.x/8,prota.y/8)>2) + x*=8; + y*=8; + if(i==1) + robots[i]=robot(x,y); + muerto[i]=0; + break; + else + harf=0; + for(j=1;j<=i-1;j++) + if(robots[j].x<>x && robots[j].y<>y) + harf++; + end + end + if(harf==i-1) + robots[i]=robot(x,y); + muerto[i]=0; + break; + end + end + end + end + end + graph=0; + protax=prota.x; + protay=prota.y; + if(espe) + timer[2]=0; + while(/*fading ||*/ timer[2]<200) + frame; + end + delete_text(all_text); + espe=0; + end + loop + frame; + if(cogido) + repeat + frame; + until(ya) + break; + end + if((key(_up) || key(_c_up) || key(_c_home) || key(_c_pgup)) && prota.y>0) + while(key(_up) || key(_c_up)) + frame; + end + protay-=8; + mueve=1; + end + if((key(_down) || key(_c_down) || key(_c_end) || key(_c_pgdn)) && prota.y<191) + while(key(_down) || key(_c_down)) + frame; + end + protay+=8; + mueve=1; + end + if((key(_left) || key(_c_left) || key(_c_home) || key(_c_end)) && prota.x>0) + while(key(_left) || key(_c_left) || key(_c_home) || key(_c_end)) + frame; + end + protax-=8; + mueve=1; + end + if((key(_right) || key(_c_right) || key(_c_pgup) || key(_c_pgdn)) && prota.x<311) + while(key(_right) || key(_c_right) || key(_c_pgup) || key(_c_pgdn)) + frame; + end + protax+=8; + mueve=1; + end + if(key(_c_center)) + while(key(_c_center)) + frame; + end + mueve=1; + end + if(key(_t)) + while(key(_t)) + frame; + end + loop + x=rand(0,39); + y=rand(0,24); + j=0; + for(i=1;i<=num_robots;i++) + if(fget_dist(x,y,robots[i].x/8,robots[i].y/8)>2) + j++; + end + end + if(j==num_robots) + break; + end + end + protax=x*8; + protay=y*8; + mueve=1; + end + if(key(_u)) + while(key(_u)) + frame; + end + protax=rand(0,39)*8; + protay=rand(0,24)*8; + mueve=1; + end + if(key(_f1)) + graph=14; + x=160; + y=100; + z=-20; + while(key(_f1)) + frame; + end + repeat + frame; + until(key(_space) || key(_enter)) + graph=0; + end + if(mueve==1) + prota.x=protax; + prota.y=protay; + mueve=0; + mueve_robots(); + end + end + //signal(prota,s_kill); + //signal(type robot,s_kill); + muertos=0; + cogido=0; + ya=0; + end +END + +Process Protag(x,y) +PRIVATE + imagen=0; + imagenes[12]=1,9,10,11,12,13,12,13,12,11,10,9,1; + saludando; + esp_frame; + coge_robot; + +BEGIN + graph=imagenes[imagen]; + timer[1]=0; + loop + frame; + if(coge_robot=collision(type robot)) + cogido=1; + if(coge_robot.graph==3) + write(1,160,100,4,"­­ PERO QU HACES !!"); + else + write(1,160,100,4,"­­ TE HAN COGIDO !!"); + end + write(1,160,199,7,"Pulsa una tecla"); + repeat + frame; + until(key(_space) || key(_enter)) + /*fade_off(); + while(fading) + frame; + end*/ + delete_text(all_text); + ya=1; + frame; + end + if(saludando==0 && timer[1]=>500) + saludando=1; + end + if(saludando==1) + if(imagen<12) + esp_frame++; + if(esp_frame==2) + esp_frame=0; + imagen++; + graph=imagenes[imagen]; + end + else + saludando=0; + imagen=0; + timer[1]=0; + end + end + if(muertos==num_robots) + cogido=1; + write(1,160,100,4,"­­ MUY BIEN !!"); + write(1,160,199,7,"Pulsa una tecla"); + num_robots++; + repeat + frame; + until(key(_space) || key(_enter)) + /*fade_off(); + while(fading) + frame; + end*/ + delete_text(all_text); + ya=1; + if(num_robots>max_robots) + //exit("­Te has pasado el juego!",0); + end + frame; + end + end +END + +Process Robot(x,y) +PRIVATE + imagen=0; + imagenes[3]=2,6,7,8; + ya_mue; + esp_frame; + +BEGIN + graph=imagenes[imagen]; + loop + frame; + if(collision(type robot)) + graph=3; + if(!ya_mue) + muertos++; + ya_mue=1; + end + end + if(graph<>3) + esp_frame++; + if(esp_frame==2) + esp_frame=0; + imagen=(imagen+1)mod 3; + graph=imagenes[imagen]; + end + end + end +END + +Process mueve_robots() +BEGIN + for(i=1;i<=num_robots;i++) + if(robots[i].graph==3) + muerto[i]=1; + end + if(!muerto[i]) + if(robots[i].xprota.x) + robots[i].x-=8; + end + if(robots[i].yprota.y) + robots[i].y-=8; + end + end + end +END diff --git a/ediv/ideQT/main.cpp b/ediv/ideQT/main.cpp index e77dcf7..dd5c93e 100644 --- a/ediv/ideQT/main.cpp +++ b/ediv/ideQT/main.cpp @@ -24,6 +24,9 @@ int main( int argc, char** argv ) RegCloseKey(subkey); Main.personal_folder.setLatin1((char*)datos); } + else { + Main.personal_folder.setLatin1(".\\"); + } #else Main.personal_folder.setLatin1(getenv("HOME")); #endif diff --git a/ediv/src/dlls/dlls.suo b/ediv/src/dlls/dlls.suo index 0611bbe6b0e2d50ebfab347f9e3b25e7642ca54a582688a1213c04d2375db840..50fdb4ec5f6da689441108507a47d97a36a03f3f95ab682d619010e1a66c8d7c 100644 GIT binary patch delta 1030 zcmaJ=OHWf#5T0|nAbs3IA3$j%0jz=x2!*0CB9fq`K!qB%EHu0$3c}S8K<(ZQG8+>T zqi!%!6T)4RsDULC$`4RUj98yY(uHUOe&-gFt~|+iI_I0|%zWq0i9Z(cXJX-@VyPga zN?^};qO1zX!unS8{M53@0u^uINwrm@eAp_mkHya1O8%|3^NKadO}VNuksZ$wPmNt$ zi{N}q6UQ~L>QpF;H^Y9POH9#es->E2${`_$tUxJ1yrH=*doY|hIpk^9F`>*I;Yr6` z@q%|9t9CcM%3;|JHDILjIu%V6gVHi+)?J-uH>vcmp}S+kE_*G=j7oW8CRvn8>IE@- zAqZy%X`~81Xbme;bRYH75Z$J6(qR#ObYUByF}g~lGzeD@TtrJ&Y}Y~RAQ3ei@Las_ zfF=KZ1D-yB=&uax2Q>_Ws98pgBgGhvfEvbWPDbePPGCn~epK!?;(-;LsZXy-*!`eo z6XvIoccKTABKH%R9e{i5YJyuZJ_AYM3-A^A27Cv806&3k;1{rmJbMo=pIrKf96j2f7WUUD(-rx5e%!}d@-0hEwY2G;z$Q>U4wNGu*g&P8>pB!&PCNM ze%)Tn>tRj!WI81*c%!u+Q#|%x6*DbY_-)%!RUt)i!WXqqo9&H4vQD!RpV>;X!fUqD z9z6g6 delta 879 zcmZuvO-NKx6#nk>X_GT=)EUPgG(oZwf*Q?!j51-&G^=_3v~!U(YSCmdK1wWdf_5z; z&!%Y84@4A!`Dj~^ErJMj9rUv)X;aW!^fmv1wvH#SF5~IJ5WI)yqa_(cAz{%WRLB7k&o6ym%gJxBybuRFban& z;JuDIj1&fV=2LW?qzl-nwOW%RH9~9R_(o6zSfp h-A+;?Yww;kg}%Rd`XT!dcmEMHPv(4ka` +# include + unsigned int tiempo; + unsigned int ultimo_tiempo; +#else +# error ¡adapta las rutinas de timer a Linux! +#endif + +#include + #include "export.h" //#include "../../shared/varindex.h" @@ -152,6 +163,7 @@ int ExportaFuncs(EXPORTAFUNCS_PARAMS) FUNCTION("define_region",5,eDiv_DefineRegion) ; ENTRYPOINT( first_load ) ; + ENTRYPOINT(frame); // POR HACER: funciones signal, system, ignore_error... @@ -201,7 +213,7 @@ int eDiv_GetId(FUNCTION_PARAMS) { return ( fp->procs_s[ fp->proc_orden[ i ] ].id ) ; } - } + } *last_type = 0 ; return 0 ; } @@ -242,6 +254,12 @@ void first_load(FUNCTION_PARAMS) { int i ; + #ifdef _WIN32 + struct timeb tiempob; + ftime(&tiempob); + ultimo_tiempo=tiempob.time*100+tiempob.millitm/10; + #endif + for ( i = 0 ; i < 32 ; i++ ) { regions[i].x = 0 ; @@ -253,8 +271,23 @@ void first_load(FUNCTION_PARAMS) fp->regions = regions ; fp->existe.regions = 1 ; - } +void frame(FUNCTION_PARAMS) +{ + int i; + int timer; + #ifdef _WIN32 + struct timeb tiempob; + ftime(&tiempob); + tiempo=tiempob.time*100+tiempob.millitm/10; + timer=globalptr("timer"); + for(i=0;i<10;i++) + fp->mem[timer+i]+=tiempo-ultimo_tiempo; + ultimo_tiempo=tiempo; + #endif +} + + diff --git a/ediv/src/dlls/export.h b/ediv/src/dlls/export.h index c4044a2..bdbaf0a 100644 --- a/ediv/src/dlls/export.h +++ b/ediv/src/dlls/export.h @@ -271,6 +271,7 @@ struct _fun_params{ TYPEOF_Critical_Error *Critical_Error ; TYPEOF_GetVarOffset *GetVarOffset ; TYPEOF_Stub_Quit *Stub_Quit ; + int imem_max; } ; diff --git a/ediv/src/dlls/graphics/graphics.vcproj b/ediv/src/dlls/graphics/graphics.vcproj index a4bb590..58122ac 100644 --- a/ediv/src/dlls/graphics/graphics.vcproj +++ b/ediv/src/dlls/graphics/graphics.vcproj @@ -105,6 +105,7 @@ SuppressStartupBanner="TRUE" IgnoreDefaultLibraryNames="LIBCMTD.lib" ModuleDefinitionFile=".\graphics.def" + GenerateDebugInformation="TRUE" ProgramDatabaseFile=".\Debug/graphics.pdb" ImportLibrary=".\Debug/graphics.lib"/> //#include #include "export.h" -#include "errors.h" +//#include "errors.h" // Falta añadir errors.h al CVS #include #include "graphics.h" #include "SDL_rotozoom.h" +#define ERR_CANNOTOPENFPG 105 +#define ERR_INVALIDFPGHEADER 106 +#define ERR_INVALIDMAPCODE 110 + +#define Miedzy(x,a,b) (((x) >= (a)) && ((x) <= (b))) + //#include "varindex.h" @@ -213,6 +219,22 @@ int ExportaFuncs(EXPORTAFUNCS_PARAMS) return TRUE; } +/* + * int IntersectionRR(int rc1left,int rc1top,int rc1right,int rc1bottom,int rc2left,int rc2top,int rc2right,int rc2bottom) + * Comprueba si hay colisión entre dos regiones rectangulares. + * + * Devuelve: + * 0 - No hay colisión + * 1 - Hay colisión + */ +int IntersectionRR(int rc1left,int rc1top,int rc1right,int rc1bottom,int rc2left,int rc2top,int rc2right,int rc2bottom) +{ + return ((Miedzy(rc1left,rc2left,rc2right) || Miedzy(rc1right,rc2left,rc2right) || + Miedzy(rc2left,rc1left,rc1right) || Miedzy(rc2right,rc1left,rc1right)) && + (Miedzy(rc1top,rc2top,rc2bottom) || Miedzy(rc1bottom,rc2top,rc2bottom) || + Miedzy(rc2top,rc1top,rc1bottom) || Miedzy(rc2bottom,rc1top,rc1bottom))); +} + /* A continuación las funciones que queremos exportar. Para una mayor * sencillez las hemos puesto en este mismo archivo, aunque puede ser * aconsejable ponerlas en archivos aparte. @@ -226,14 +248,19 @@ int eDIV_COLLISION(FUNCTION_PARAMS) int a, i ; SDL_Rect r1 , r2 ; a = getparm() ; + + id1 = fp->procs_s[ fp->proc_orden[ *fp->proceso_actual ] ].id ; + + g1 = local("graph",id1) ; + f1 = local("file",id1) ; + if ( files[f1].existe == 0 || files[f1].mapa[g1].existe == 0 ) + return 0; + // Si se le pasa un ID - if ( a < 4000000 ) + //if ( a < 4000000 ) + if(aimem_max) { - id1 = fp->procs_s[ fp->proc_orden[ *fp->proceso_actual ] ].id ; - g1 = local("graph",id1) ; - f1 = local("file",id1) ; - if ( files[f1].existe == 0 || files[f1].mapa[g1].existe == 0 ) - return -1 ; + if(a==id1) return 0; r1.x = local("x",id1) ; r1.y = local("y",id1) ; r1.w = files[f1].mapa[g1].Surface->w ; @@ -242,47 +269,66 @@ int eDIV_COLLISION(FUNCTION_PARAMS) g2 = local("graph",id2) ; f2 = local("file",id2); if ( files[f2].existe == 0 || files[f2].mapa[g2].existe == 0 ) - return -1 ; + return 0; r2.x = local("x",id2) ; r2.y = local("y",id2) ; r2.w = files[f2].mapa[g2].Surface->w ; r2.h = files[f2].mapa[g1].Surface->h ; //Colision barata :P - if (!( (r2.x > r1.x && r2.x > r1.x + r1.w) || (r2.x+r2.w < r1.x && r2.x+r2.w r1.x && r2.x > r1.x + r1.w) || (r2.x+r2.w < r1.x && r2.x+r2.w r1.y && r2.y > r1.y + r1.h) || (r2.y+r2.h < r1.y && r2.y+r2.hnum_procs ; i++ ) + + if(*type_scan!=a) { + *id_scan=0; + *type_scan=a; + } + + for ( i = *id_scan+1 ; i < *fp->num_procs ; i++ ) { - id1 = fp->procs_s[ fp->proc_orden[ i ] ].id ; + id2 = fp->procs_s[ fp->proc_orden[ i ] ].id; + if(id2==id1) continue; + printf("collision: %d\n",id2); //Si el proceso se corresponde con el type - if ( reserved("process_type",id1) == a ) + if ( reserved("process_type",id2) == a ) { - g1 = local("graph",id1) ; - f1 = local("file",id1) ; - if ( files[f1].existe == 0 || files[f1].mapa[g1].existe == 0 ) - return -1 ; + printf("collision: encontrado: id %d\n",id2); r1.x = local("x",id1) ; r1.y = local("y",id1) ; r1.w = files[f1].mapa[g1].Surface->w ; r1.h = files[f1].mapa[g1].Surface->h ; - id2 = a ; + //id2 = a ; g2 = local("graph",id2) ; f2 = local("file",id2) ; if ( files[f2].existe == 0 || files[f2].mapa[g2].existe == 0 ) - return -1 ; + continue; r2.x = local("x",id2) ; r2.y = local("y",id2) ; r2.w = files[f2].mapa[g2].Surface->w ; r2.h = files[f2].mapa[g1].Surface->h ; //Colision barata :P - if (!( (r2.x > r1.x && r2.x > r1.x + r1.w) || (r2.x+r2.w < r1.x && r2.x+r2.w r1.y && r2.y > r1.y + r1.h) || (r2.y+r2.h < r1.y && r2.y+r2.h r1.x && r2.x > r1.x + r1.w) || (r2.x+r2.w < r1.x && r2.x+r2.w r1.y && r2.y > r1.y + r1.h) || (r2.y+r2.h < r1.y && r2.y+r2.himem_max-iloc_len) critical_error(8); // demasiados procesos en ejecución memcpy(&mem[procs_s[num_proc].id],&mem[iloc],iloc_pub_len<<2); reserved("process_id",procs_s[num_proc].id)=procs_s[num_proc].id; @@ -548,7 +549,8 @@ int proceso( int num, int padre ) if ( devolver > 0 && no_devuelve == 0 ) { - pila[++sp] = 0 ;// AQUI SE DEBERA DEVOLVER EL ID + //pila[++sp] = 0 ;// AQUI SE DEBERA DEVOLVER EL ID + pila[++sp]=procs_s[num_proc].id; devolver-- ; } diff --git a/ediv/src/stub/stub.c b/ediv/src/stub/stub.c index abf4bcb..505d5d7 100644 --- a/ediv/src/stub/stub.c +++ b/ediv/src/stub/stub.c @@ -322,7 +322,7 @@ int main(int argc, char* argv[]) switch( event[0].type ) { case SDL_QUIT: - assert(0); + //assert(0); stub_quit(0) ; break ; case SDL_NOEVENT: diff --git a/ediv/src/visual c/ediv_ws.suo b/ediv/src/visual c/ediv_ws.suo index 31071c8dc6e9d7ec0696740ab4dccd6d730391925b5d0fbff5e6c03e7bf4b0dc..85d99a1e156046a7fa4ce28289d19a9e03e4e3a2cb50813d5fb10923ba42ef1b 100644 GIT binary patch delta 1531 zcmai!T}+!*7{||f`$2&~DgAH=$U7*|mBHACP=t{>+LAcBQRplxDuve3QCci5gHqRd zVY0-V(Z_hSCJTv)L!*f?S>kTIG`sMUL}KE_%-rk$lwKfA_a?t{p7WfK z=R6x&Zod@D_L*yaOh{yWlIm2!Sy809*hwAOgfXa9%XZ927ASFHU@jJ^>a$5~RQ)xCEBKGDw3JkO3co z;(>+payqA{6gsslm=u>`W#isqd2D(nJXaW2xFW%5{DSNbMUru0h?NGyQ?e(Xm=h*h z*OVKSP}AcFPV(tz4(RIXH(m12EC9P@1a!>w=rG%5SW}CL#O?l_b8xn-d zwR#neG;Pvm1QJVzX(#sPLRU z$$Kbe&+<3vPqY^))%GcE)kLw}Pg@QO|CbD_{bZ7=s+9 zpN9e`kDoZ%^(y`dd#ttopEb7En)$ibXw^|uGL1)=VJmB$(mmf@zB=in#V!whk!i_q z_kYH7-AO)7scuC(3Fo5{Jxaep-}m&>WAC|x7qY$JLX7y(e8s=~rgh&4O`d6Of^SK< zKf_M5SCGUppoK~CJ-ppj{rfj}ex;5+8(lM-=)TcP^6P3dt}XD QMRKQ>b_T3@d*&DZ51A`*00000 literal 32256 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 VunMP+TQ!UGx6Y!k`Odx9{{v3iQtAKz