Instalación y Punteros

Started by Buade, July 18, 2010, 07:15:17 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Buade

Buenos días.

Tengo un problema y un par de preguntas.
Esperaba que pudieran ayudarme con el primero, quizá esté haciendo algo mal... Sencillamente el compilador no reconoce constantes o funciones, como si necesitara modulos que no encuentra. Leí que en 'Variables de entorno', de Windows, debería haber una variable de nombre PATH con las rutas de las carpetas 'bin', 'libs', etc. No había ninguna, así que la agregue manualmente, pero sigue ocurriendo lo mismo.

Debido a esto por el momento me limité a usar fenix 0.92a, pero supongo que mi pregunta (que no tiene nada que ver con lo anterior), no varía:

Estaba intentando recorrer una lista dinámica, para lo que hice la comparación 'while (puntero != 0)', pero no lo admitió, luego probé con 'null' pero no lo reconoce y finalmente intenté simplemente con while (puntero) pero nada :P

Creí que aún necesitaba una constante que represente la dirección nula, que no encontraba, pero después se me ocurrió comparar un puntero con otro y tampoco funcionó :S. ¿Fenix/Bennu no lo soporta? ¿O estoy haciendo algo mal? ¿Hay otra forma de hacer esto?

Y aprovecho la oportunidad para hacer otra consulta que no encontré en la documentación. ¿Se pueden pasar variables por referencia como parámetro? Hasta ahora solucioné ese asunto creando otro puntero, pero si existe esa funcionalidad mejor :)

Gracias

FreeYourMind

Antes de nada,

Welcome to your DOOM!




Sobre tu problema, lo mejor es que pongas aqui el código, porque no entiendo muy bien cual puede ser el verdadero problema.

Sabes que hay que importar los modulos de las funciones que usas en Bennu (usando el fichero bgdc.import por ejemplo) ?

Buade

#2
Ah, no lo sabía, probablemente sea eso entonces. ¿Hay que crear un fichero con los dlls que uses? ¿Dónde tiene que estar?

Lo del código.. estaba implementando una lista para otra cosa:


type t_nodoL
  t_dato          dato;
  t_nodoL pointer ant; //punteros al elemento anterior,
  t_nodoL pointer pos; //y al siguiente
end


En el proceso principal solo se agregan elementos a la lista y despues se llama a un proceso que guarda la lista en un archivo.

guardarDatos(RUTA_DATOS, &lista); <-- 'lista' es privada

Como no encontré la forma de pasar parametros por referencia, lo hice con un puntero, por eso en el argumento puse '&lista' y en guardar hay un doble puntero.


process guardarDatos(string ruta, t_nodoL pointer pointer lista)
private
  int baseDatos;
begin  
  baseDatos = fopen(ruta, O_WRITE);
  fseek(baseDatos, 0, 0); //Esta linea no se si es necesaria pero por si acaso :P
  while (*lista) //<--Esta forma fué la única que compiló, pero terminó en un error de ejecución.
     fwrite(baseDatos, (*lista).dato);
     *lista = (*lista).pos;
  end
  fclose(baseDatos);
end


Mi pregunta era cómo saber cuando un puntero es nulo o igual a otro, porque las comparaciones del tipo if (puntero1 == puntero2) o if (puntero!=0) no compilan.

Gracias de nuevo =)

FreeYourMind

Lo que tu pones no me compila.

Yo creo que estas usando cosas más al estilo c/c++ que Bennu, no hace falta tanta complejidad....

Una estructura se declara así:

STRUCT t_nodoL;
   t_dato          dato;
   pointer ant; //punteros al elemento anterior,
   pointer pos; //y al siguiente
END

Así ya compila, de todos modos revisalo porque no se si esta bien, aparte de esto no se para que quieres usar un puntero para salvar datos, para esto sólo necesitas la estrutura con los datos...

process guardarDatos(string ruta, pointer lista)
private
   int baseDatos;
begin 
   baseDatos = fopen(ruta, O_WRITE);
   fseek(baseDatos, 0, 0); //Esta linea no se si es necesaria pero por si acaso :P
   while (*lista) //<--Esta forma fué la única que compiló, pero terminó en un error de ejecución.
      fwrite(baseDatos, t_nodoL);
      *lista = t_nodoL.pos;
   end
   fclose(baseDatos);
end



FreeYourMind

las dll's que usas es donde estan implementadas las funciones bennu que utilizes en tu juego, para saber de donde proviene cada funcion ejecuta el fichero 'ListarFunc.bat' que te adjunto que te generará el fichero con esta info 'function-list.txt'.

En el 'bgdc.import' pones el nombre de los modulos a utilizar y listo.

Te pongo el contenido de los 2 ficheros para que los veas, pero edita el bgdc.import y pon solo los modulos que utilizes

bgdc.import
-----------

mod_wm
mod_video
mod_key
mod_scroll
mod_timers
mod_time
mod_text
mod_mouse
mod_map
mod_proc
mod_sound
mod_file
mod_rand
mod_screen
mod_grproc
mod_draw
mod_math
mod_joy
mod_say


ListarFunc.bat
-------------

@echo off
echo BENNU FUNCTIONS > function-list.txt
echo --------------- >> function-list.txt
for %%i in (lib*.dll) do echo %%i && moddesc -i- %%i >> function-list.txt && echo ------------------------------------------------------- >> function-list.txt
for %%i in (mod*.dll) do echo %%i && moddesc -i- %%i >> function-list.txt && echo -------------------------------------------------------



Drumpi

#5
Bennu sí admite la comparación de punteros, así como el paso por referencia y todo eso. Estoy mirando lo que has puesto, y no le veo ningún problema a simple vista (es más, creo que es más correcto que lo que ha puesto free, que ha creado punteros a enteros), tiene que ser alguna otra cosa, como por ejemplo, que hayas declarado los tipos en la zona de globales, locales, privadas o públicas: no deben ir en ninguna de ellas.

Siempre me lío: paso por referencia es ese método de paso de parámetros por el que no se crea una copia ¿verdad? si es así, es tal como lo has hecho, con punteros.
En el segundo código que pones, asumo que lista es un puntero a otro puntero que señala a la lista enlazada que quieres crear, por lo que creo que tienes un error en el segundo código:

[code language="bennu"]process guardarDatos(string ruta, t_nodoL pointer pointer lista)
private
  int baseDatos;
begin  
  baseDatos = fopen(ruta, O_WRITE);
  fseek(baseDatos, 0, 0); //Esta linea no es necesaria en absoluto
  while (*lista)
     fwrite(baseDatos, (*(*lista)).dato);  //revisa esto
     *(*lista) = (*(*lista)).pos;   //y esto
  end
  fclose(baseDatos);
end[/code]

Creo que al ser un pointer pointer, el dato a leer requiere de un doble asterisco (uno para leer la posición de memoria del puntero padre, y otra para leer el dato del nodo al que apunta el puntero padre). Creo que por eso tampoco te funcionó el while, porque comprueba el valor de lista, que es la dirección del otro puntero y devuelve siempre TRUE (!=0).
Lo de recorrer la lista ya es más peliagudo. Los punteros en Bennu aun los tengo bastante verdes. Sé que existe una constante llamada NULL para estos menesteres, y en ocasiones yo he comparado con 0 sin ningún problema, pero la mayoría de las veces, sobre todo por las prisas, lo que hacía era tener una variable dentro del nodo que indicaba si existía o no otro nodo, poniéndolo a TRUE o FALSE.

De todas maneras, aquí recomiendo mostrar el código y la intervención de alguien con más experiencia.
Ah, y el uso de globals también. Que no sea una práctica recomendada, aquí nadie nos lo prohibe y son muy utilizadas. Y las públicas, una vez se aprenden a usar, son muy límpias a la hora de consultar variables ajenas.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

DjSonyk

Quote from: Drumpi on July 18, 2010, 01:26:02 PM
Siempre me lío: paso por referencia es ese método de paso de parámetros por el que no se crea una copia ¿verdad? si es así, es tal como lo has hecho, con punteros.

Exacto,llamar a un metodo de clase ,en el caso de Bennu podriamos decir FUNCTION o PROCESS,pasando los parametros por referencia implica la modificación del dato original,los cambios los hace directamente en la zona de memoria del parametro.

Si la forma de definir punteros ,ya que con bennu aun no lo he mirado,es igual que en C,y veo que es muy parecida seria **lista,sin lo parentesis,ya como bien a dicho Drumpi es un puntero a puntero.

Buade

Quote from: Drumpi on July 18, 2010, 01:26:02 PM
Bennu sí admite la comparación de punteros, así como el paso por referencia y todo eso. Estoy mirando lo que has puesto, y no le veo ningún problema a simple vista (es más, creo que es más correcto que lo que ha puesto free, que ha creado punteros a enteros), tiene que ser alguna otra cosa, como por ejemplo, que hayas declarado los tipos en la zona de globales, locales, privadas o públicas: no deben ir en ninguna de ellas.

Siempre me lío: paso por referencia es ese método de paso de parámetros por el que no se crea una copia ¿verdad? si es así, es tal como lo has hecho, con punteros.
En el segundo código que pones, asumo que lista es un puntero a otro puntero que señala a la lista enlazada que quieres crear, por lo que creo que tienes un error en el segundo código:

[code language="bennu"]process guardarDatos(string ruta, t_nodoL pointer pointer lista)
private
  int baseDatos;
begin  
  baseDatos = fopen(ruta, O_WRITE);
  fseek(baseDatos, 0, 0); //Esta linea no es necesaria en absoluto
  while (*lista)
     fwrite(baseDatos, (*(*lista)).dato);  //revisa esto
     *(*lista) = (*(*lista)).pos;   //y esto
  end
  fclose(baseDatos);
end[/code]

Creo que al ser un pointer pointer, el dato a leer requiere de un doble asterisco (uno para leer la posición de memoria del puntero padre, y otra para leer el dato del nodo al que apunta el puntero padre). Creo que por eso tampoco te funcionó el while, porque comprueba el valor de lista, que es la dirección del otro puntero y devuelve siempre TRUE (!=0).
Lo de recorrer la lista ya es más peliagudo. Los punteros en Bennu aun los tengo bastante verdes. Sé que existe una constante llamada NULL para estos menesteres, y en ocasiones yo he comparado con 0 sin ningún problema, pero la mayoría de las veces, sobre todo por las prisas, lo que hacía era tener una variable dentro del nodo que indicaba si existía o no otro nodo, poniéndolo a TRUE o FALSE.

De todas maneras, aquí recomiendo mostrar el código y la intervención de alguien con más experiencia.
Ah, y el uso de globals también. Que no sea una práctica recomendada, aquí nadie nos lo prohibe y son muy utilizadas. Y las públicas, una vez se aprenden a usar, son muy límpias a la hora de consultar variables ajenas.

Bennu lo admite? Entonces debe ser que fenix 0.92a no. Mejor sigo con Bennu xD.

Lo del codigo de guardar habia visto en un ejemplo de Bennu que directamente accedian con puntero.algo, por eso lo dejé así. Igual probé de la otra forma y pasa lo mismo :/. Deben ser problemas de fenix arreglados después.

Lo de las variables globales es cierto, el problema es que queria llamar al process con mas de una lista pero bueno.

Voy a probar con Bennu, gracias por el momento =)

Prg

#8
para usar bennu hay tres formas:
1)
mira, si no quieres poner las variables de entorno, entonces necesitas copiar todas las librerias al directorio de tu juego incluyendo el bgdc y el bgdi (me van a ahorcar por desordenado XD ) y para compilar desde cmd solo haces bgdc archivo.prg (habiéndote colocado antes en el directorio con cd)
2)
también puedes configurarte un ide, hay varios archivos de configuración rondando en un tema en el foro. luego copias todas las librerías de la instalación de bennu  (me refiero a las que están en externals, mod, etc)  a la carpeta bin de la instalación, y por ultimo le dices al ide que compile de la carpeta bin (donde ya tienes todas las librerías y el compilador e intérprete), con esto ya debería funcionar.
el link de ides: http://forum.bennugd.org/index.php?topic=165.0
3)
también puedes agregar las rutas al path del sistema, solo debes agregar una ruta por cada carpeta de instalación en la variable path, cada una separada por ; creo que eso ya lo sabrás. para compilar pues usarías el cmd y pondrías directamente bgdc archivo.prg

lo de los punteros
me gusta el ejmplo de Drumpi

yo usé eso en lsl y ldl así como en intentos de árbol. compartiré un código si te sirve de el de árboles

[code language="bennu"]
type c4Nodo                                  //nodo de los árboles
int dat;
c4Nodo *sig[2];
end

function conecte4_crea_arbol(c4Nodo **arbol,string cad)
private
   int f67=0;
   string v;
begin
   f67=fopen(cad, o_read);//abre archivo
   arbol=conecte4_toma(f67,arbol);//comienza a crear arbol
   fclose(f67);//cierra archivo
end

//*******************************************************************************************//
//crea un nodo de un árbol
//*******************************************************************************************//

function conecte4_toma(int f,c4Nodo ** N)// aqui uso doble puntero como tu
private
   int dval=0;
begin
   if(fread(f,dval))//si puede leer
      if (dval==-1)//si el valor de lectura es -1
         (*N)=alloc(sizeof(c4Nodo));//crea un nuevo nodo aqui trabajo con el puntero, asi que solo uso un *
         (*(*N)).dat=-1;//le asigna el valor de -1 . uso doble * entre parentesis para que el compilador no de problemas
         from z=0 to 1;
            conecte4_toma(f,&(*(*N)).sig[z]);//intenta crear dos nuevas ramas recursivamente
         end
      end
      if (dval==-2)//si el valor es -2
         N=null;//no crea rama
         return;//sale
      end
      if (dval>=0)//si el valor es =>0
         *N=alloc(sizeof(c4Nodo));//crea un nuevo nodo
         (*(*N)).dat=dval;//y asigna el valor del dval al campo dat
         from z=0 to 1;
            (*(*N)).sig[z]=Null;//pone en nullo las posibles ramas hijas
         end
      end
   end
end

//*******************************************************************************************//
//elimina el árbol que se le pasa como parámetro
//*******************************************************************************************//

function conecte4_elimina_arbol(c4Nodo *arbol)
begin
   conecte4_elim(arbol);
end

//*******************************************************************************************//
//elimina el nodo y sus hijos recursivamente
//*******************************************************************************************//

function conecte4_elim(c4Nodo * N)
private
   val;
begin
   if (n<>NULL)
      from z=0 to 1;
         conecte4_elim((*N).sig[z]);
      end

      free(N);
   end
end

//*******************************************************************************************//
//imprime los valores del árbol que se le pasa como parámetro
//*******************************************************************************************//

function conecte4_imprime_arbol(c4Nodo *arbol)
begin
   conecte4_imp(arbol);
end

//*******************************************************************************************//
//imprime el valor del nodo y avanza entre todos los nodos
//*******************************************************************************************//

function conecte4_imp(c4Nodo * N)
private
begin
   if (n<>null)
      say((*N).dat);
      from z=0 to 1;
         //           say((*N).sig[z]);
         conecte4_imp((*N).sig[z]);
      end
   end
end[/code]

saludos :)
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Buade

#9
Muchas gracias Prg, lo de los punteros entonces está bien para Bennu, el problema es q no lo logro hacer andar :P

Hice lo que dijiste pero el IDE (especificamente Flamebird MX) sencillamente no encuentra las funciones, como si los modulos no estuvieran.

Probé también compilar desde el cmd con bgdc archivo.prg, estando todo en la misma carpeta, pero devuelve 'archivo.prg: doesn't exist or isn't version 7 DCB compatible'. ¿Alguna idea?.

PD: Ya sé que donde dice 'archivo' va el nombre del mío, eh xD jaja

Prg

#10
ok, si quieres el flamebird entonces debemos colocar los módulos donde el flamebird los buscará. primero ya debes tener todos los módulos en una carpeta vd?

en alguna parte de la configuración del flamebir debe venir una opción para editar la ruta de compilación, en esa opción debes colocar la ruta en donde tienes todos los módulos juntos. después de eso recuerdo que funcionaba.

no puedo instalarlo porque no funciona en win7 64b (aunque lo ponga en modo compatibilidad me saca al darle a preferencias).

si gustas puedo ayudarte a instalar otro ide (aprovechando que en esta pc no tengo ninguno instalado y usaba blog de notas XD)
yo siempre he usado este:
http://www.contexteditor.org/

lo instalas y luego descargas esto:
http://forum.bennugd.org/index.php?action=dlattach;topic=165.0;attach=43

y lo abres, luego en
C:\Program Files (x86)\ConTEXT\Highlighters (o C:\Program Files\ConTEXT\Highlighters)
copias lo que viene en el comprimido en
ConTEXT\Highlighters\


haces lo mismo con lo que viene en template:
C:\Program Files (x86)\ConTEXT\Template
copiar del comprimido
ConTEXT\Template\

ahora das doble click en el archivo fixbennu.reg que viene en el comprimido.

ahora abres el context, seleccionas options / environments options/Execute keys/add y escribes: "prg"
sin las comillas
cierras el programa y vuelves a ejecutar el fixbennu.reg

ahora revisa de nuevo options / environments options/Execute keys y ahora debe decir prg,bennu


ahora sólo falta configurar las rutas de compilación y del intérprete.

dale click a f9 (abajo de los textos prg,bennu)
y en la ruta que dice execute cámbiala por la ruta donde tienes todas las librerías juntas y selecciona el bgdc

en f10 colocas la misma ruta de carpeta pero el bgdi

dale ok y ahora prueba tu ide configurado

file/new
tools/set highligther/bennu game development

copia lo siguiente

[code language="bennu"]import "mod_say"
begin
say("hola");
end[/code]

presiona f9

en la consola del context aparecerá que la compilación resultó exitosa (si esto no sucede avisa)
presiona f10
la consola dirá

Quote> Executing: C:\Program Files (x86)\ConTEXT\ConExec.exe "C:\BennuGD\bin\bgdi.exe" hola

hola
> Execution finished.
o algo parecido


si te funciona me dices.
luego puedes agregar el identador de dcelso al f12 para que idente el código de bennu directamente (me dices y te paso el link, este identador es el que me funciona mejor porque no me borra el código cuando trabaja sobre el archivo que el context tiene abierto), también puedes cambiar el idioma a español desde las preferencias.


QuoteProbé también compilar desde el cmd con bgdc archivo.prg, estando todo en la misma carpeta, pero devuelve 'archivo.prg: doesn't exist or isn't version 7 DCB compatible'. ¿Alguna idea?.
esto lo debe decir el intérprete no el compilador.
debiste hacer:
bgdc archivo.prg

y si compila hacer:
bgdi archivo.dcb

pd: me emocioné XD
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Drumpi

Lo raro es que funcione con Bennu y no con Fenix (bueno, no tan raro, con los bugfixes), porque lo que es la sintaxis, no hay cambios.
De todas maneras, recomiendo usar fread y fwrite con variables tipo INT, BYTE, WORD, etc, para evitar problemas (ya que detecta el tipo de dato automáticamente, no vaya a ser que le de por detectar un tipo POINTER).

Yo bennu no lo tengo instalado: tengo una carpeta con las diversas versiones de Bennu según las voy probando (ya me ha pasado con fénix, necesitar recurrir a una versión anterior por un cambio problemático), y para compilar/ejecutar uso un script que llamo zz_compil.bat (lo de zz es para tenerlo siempre al final de la lista, bien visible):

set BENNUROOT=c:/BennuGD
set VERSION=r147
set JUEGO=mijuego
set PATH=%BENNUROOT%/binarios/%VERSION%/bin;%BENNUROOT%/binarios/%VERSION%/externals;%BENNUROOT%/binarios/%VERSION%/libs;%BENNUROOT%/binarios/%VERSION%/modules;%PATH%
bgdc -g %JUEGO%.prg
bgdi %JUEGO%.dcb


Así lo compilo, además, con el modo debug, para depurar. Tengo también otro sin la última línea para ver los errores de compilación. Esto lo ejecuto desde el CMD o desde la ventanita de comandos de notepad++.
Conste que yo tengo una carpeta para todas las cosas de bennu, y en ella una carpeta de proyectos, otra de pruebas, ayuda... y obviamente la de binarios, con una carpeta con el nombre r[numero de versión] por cada versión de bennu que tengo. Dentro están la 4 típicas carpetas bin, externals, libs y modules.

Límpio, sin instalaciones, ordenadito y sin dependencias raras.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Windgate

Veo todo lo que decís, y me parecen soluciones muy buenas, pero hago mi recomendación personal por si sirve de algo:

1) Instala Bennupack
2) Usa la plantilla de mi tutorial para empezar a programar a partir de ella

Y nada más xD
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Prg

es verdad.. si instalas el bennu pack puedes comenzar directamente a programar en el notepadd ;D
así te quitas de problemas.
lo había olvidado
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

SplinterGU

pon tu codigo completo, asi vemos bien el problema, quizas haya un bug no tenido en cuenta.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2