creando un módulo

Started by DCelso, February 23, 2010, 09:05:16 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

DCelso

Hola SplinterGU,
necesito hacer lo siguiente
definir una variable en c en mi módulo, darle un valor, y luego compartirla con el exterior, para que desde el código .prg pueda acceder a ésta y cambiarle su valor.
¿Como se hace? he visto el código de mod_cd y otro y nada no capto la funcionalidad de DLVARFIXUP

parece que creas una estructura en bennu llamada cdinfo y luego compartes sus variables al exterior, pero si esto es así, como inicializo su valor y como se modifica desde mi programa prg que incluirá el módulo,
Gracias de antemano.

/* ----------------------------------------------------------------- */
/* Definicion de variables globales (usada en tiempo de compilacion) */
char * __bgdexport( mod_cd, globals_def ) =
    "STRUCT cdinfo\n"
    " current_track;\n"
    " current_frame;\n"
    " tracks;\n"
    " minute;\n"
    " second;\n"
    " subframe;\n"
    " minutes;\n"
    " seconds;\n"
    " subframes;\n"
    " STRUCT track[99]\n"
    "  audio;\n"
    "  minutes;\n"
    "  seconds;\n"
    "  subframes;\n"
    " END;\n"
    "END;\n" ;

/* ----------------------------------------------------------------- */
/* Son las variables que se desea acceder.                           */
/* El interprete completa esta estructura, si la variable existe.    */
/* (usada en tiempo de ejecucion)                                    */
DLVARFIXUP  __bgdexport( mod_cd, globals_fixup )[] =
{
    /* Nombre de variable global, puntero al dato, tama±o del elemento, cantidad de elementos */
    { "cdinfo.current_track", NULL, -1, -1 },
    { "cdinfo.current_frame", NULL, -1, -1 },
    { "cdinfo.tracks", NULL, -1, -1 },
    { "cdinfo.minute", NULL, -1, -1 },
    { "cdinfo.second", NULL, -1, -1 },
    { "cdinfo.subframe", NULL, -1, -1 },
    { "cdinfo.minutes", NULL, -1, -1 },
    { "cdinfo.seconds", NULL, -1, -1 },
    { "cdinfo.subframes", NULL, -1, -1 },
    { "cdinfo.track", NULL, -1, -1 },
    { NULL, NULL, -1, -1 }
};
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

DCelso

Splinter, esto mas o menos creo que ya lo he zanjado, a ver si estoy en lo cierto.
Lo anterior crea la variable en el ámbito de bennugd.
Para acceder a ella desde c, hay que usar GLODWORD o derivados.
Por ejemplo, para guardar un dato

GLODWORD(  mod_notes, WHOLE_NOTE_TIME ) = 1;

para leer el dato

int temp = GLODWORD(  mod_notes, WHOLE_NOTE_TIME );

Ahora tengo otras dudas que creo que son más avanzadas, tengo definidas unas constantes de tipo float, el compilador de c me da un warning de conversión a entero y luego cuando las uso en Bennu, efectivamente no son float aunque moddesc diga que sí lo son.
Como puedo solucinar este problemilla.

DLCONSTANT  __bgdexport( mod_notes, constants_def )[] =
{
{"LONGA", (BASETYPE)TYPE_FLOAT, 4},
{"CUADRADA", (BASETYPE)TYPE_FLOAT, 2},
{"REDONDA", (BASETYPE)TYPE_FLOAT, 1},
{"BLANCA", (BASETYPE)TYPE_FLOAT, 1/2.0},
{"NEGRA", (BASETYPE)TYPE_FLOAT, 1/4.0},
{"CORCHEA", (BASETYPE)TYPE_FLOAT, 1/8.0 },
{"SEMICORCHEA", (BASETYPE)TYPE_FLOAT, 1/16.0},
{"FUSA", (BASETYPE)TYPE_FLOAT, 1/32.0},
{"SEMIFUSA", (BASETYPE)TYPE_FLOAT, 1/64.0},
{"GARRAPATEA", (BASETYPE)TYPE_FLOAT, 1/128.0},
{ NULL          , (BASETYPE)0       , 0  }
};


Y otro más es que no sé porqué motivo no me funcionan las siguientes funciones de inicialización y de finalización

void  __bgdexport( mod_notes, module_initialize )()
{
    if ( !SDL_WasInit( SDL_INIT_AUDIO ) ) SDL_InitSubSystem( SDL_INIT_AUDIO );
    GLODWORD(  mod_notes, WHOLE_NOTE_TIME ) = DEF_WHOLE_NOTE_TIME;
desiredSpec.freq=22050; /* 22050Hz - FM Radio quality */
desiredSpec.format=AUDIO_S16LSB; /* 16-bit signed audio */
desiredSpec.channels=0; /* Mono */
desiredSpec.samples=8192;/* Large audio buffer reduces risk of dropouts but increases response time */
desiredSpec.callback = audio_callback;
desiredSpec.userdata = 0;
// you might want to look for errors here
SDL_OpenAudio(&desiredSpec, &obtainedSpec);
// start play audio
SDL_PauseAudio(0);
}

/* --------------------------------------------------------------------------- */

void  __bgdexport( mod_notes, module_finalize )()
{
    if ( SDL_WasInit( SDL_INIT_AUDIO ) ) SDL_QuitSubSystem( SDL_INIT_AUDIO );
}

Las defino así, pero luego en el código BennuGD cuando pongo el import "mod_notes" y uso alguna función de esta librería veo que no está inicializada, es decir no pasa por lo que tengo puesto en void  __bgdexport( mod_notes, module_initialize )().

Para salir del paso, he creado una función notes_init() que hace justo eso y que el usuario debe de llamar obligatoriamente antes de poder usar el módulo.

¿Como solvento esto también? Gracias.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

para floats te la vas a tener que apañar vos a mano... mira el dlvarcc.h, y como se acceden a los floats en el core para darte una idea...

declaras constantes que son para indicar el order dentro del fixup... y que luego usaras con los LOC* o GLO*... declaras las variables como lo harias en un prg en globals_def o en locals_def, segun necesidad...

y nada, bennu se encarga solo...

la inicializacion se hace, solo que hay macros para floats por el momento...

seguro no quedo claro, pero te sugiero que veas el codigo de mod_sound...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

po mas dejao igual.
por otro lado

Quote
la inicializacion se hace, solo que hay macros para floats por el momento...
¿querias decir?
la inicializacion se hace, solo que NO hay macros para floats por el momento...
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

exacto! eso quise decir... je, ves como puedes... pon el codigo y te digo que hace falta y que esta demas...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

#5
Bueno, a ver, he estado examinando lo que me dijiste SpliterGU, y me he dado cuenta que el array de constantes no se maneja de forma distinta al de locales y globales.
Lo que comentabas de que era un índice hacia el array de constantes no es así sino que es el valor asignado a la constante. Voy a ponerte pruebas.

Primeramente, he visto que el tipo de dato más complejo de constante que has declarado es un dword, y yendo más lejos solo has declarado constantes de tipo int y de tipo dword en todo el código bennu.
Quote from: librender.c
DLCONSTANT __bgdexport( librender, constants_def )[] =
{
   { "C_SCREEN",           TYPE_DWORD, C_SCREEN },

   { "PARTIAL_DUMP",       TYPE_DWORD, 0 },
   { "COMPLETE_DUMP",      TYPE_DWORD, 1 },
   { "NO_RESTORE",         TYPE_DWORD, -1 },
   { "PARTIAL_RESTORE",    TYPE_DWORD, 0 },
   { "COMPLETE_RESTORE",   TYPE_DWORD, 1 },

   { "BACKGROUND",         TYPE_DWORD, 0 },
   { "SCREEN",             TYPE_DWORD, -1 },

   { "SCALE_SCALE2X",      TYPE_DWORD, SCALE_SCALE2X    },
   { "SCALE_HQ2X",         TYPE_DWORD, SCALE_HQ2X       },
   { "SCALE_SCANLINE2X",   TYPE_DWORD, SCALE_SCANLINE2X },
   { "SCALE_NORMAL2X",     TYPE_DWORD, SCALE_NOFILTER   },
   { "SCALE_NOFILTER",     TYPE_DWORD, SCALE_NOFILTER   },

   { NULL          , 0         ,  0  }
} ;
Quote from: mod_cd.c
DLCONSTANT __bgdexport( librender, constants_def )[] =
{
   { "C_SCREEN",           TYPE_DWORD, C_SCREEN },

   { "PARTIAL_DUMP",       TYPE_DWORD, 0 },
   { "COMPLETE_DUMP",      TYPE_DWORD, 1 },
   { "NO_RESTORE",         TYPE_DWORD, -1 },
  { "PARTIAL_RESTORE",    TYPE_DWORD, 0 },
   { "COMPLETE_RESTORE",   TYPE_DWORD, 1 },

   { "BACKGROUND",         TYPE_DWORD, 0 },
   { "SCREEN",             TYPE_DWORD, -1 },

   { "SCALE_SCALE2X",      TYPE_DWORD, SCALE_SCALE2X    },
   { "SCALE_HQ2X",         TYPE_DWORD, SCALE_HQ2X       },
   { "SCALE_SCANLINE2X",   TYPE_DWORD, SCALE_SCANLINE2X },
   { "SCALE_NORMAL2X",     TYPE_DWORD, SCALE_NOFILTER   },
   { "SCALE_NOFILTER",     TYPE_DWORD, SCALE_NOFILTER   },

   { NULL          , 0         ,  0  }
} ;
Viendo por ejemplo lo resaltado en negrita, ya me contarás cómo van a haber dos constantes con el mismo índice en el array de constantes.

Por otro lado, si examinamos el código del núcleo nos encontramos lo siguiente:
Quote from: c_main.c
   constants_def = ( DLCONSTANT * ) _dlibaddr( library, "constants_def" ) ;
   if ( constants_def )
   {
       while ( constants_def->name )
       {
           int code = identifier_search_or_add( constants_def->name ) ;
           constants_add( code, typedef_new( constants_def->type ), constants_def->code ) ;
           constants_def++ ;
       }
   }


tambíen se ve lo mismo en:
Quote from: main_core.c
main_core.c
{
   int i = 0, code ;

   while ( constants_def.name )
   {
       code = identifier_search_or_add( constants_def.name ) ;
       constants_add( code, typedef_new( constants_def.type ), constants_def.code ) ;
       i++ ;
   }

   token_init( globals_def, -1 ) ;
   compile_varspace( &global, globaldata, 1, 1, 0, NULL, DEFAULT_ALIGNMENT, 0 ) ;

   token_init( locals_def, -1 ) ;
   compile_varspace( &local, localdata, 1, 1, 0, NULL, DEFAULT_ALIGNMENT, 0 ) ;
}
hace un constants_add, que imagino yo que será para insertar en el array de constentes una constante con índice "code" (supongo que buscado en el array de constantes "identifier_search_or_add"), tipo "typedef_new( constants_def->type )" y valor "constants_def->code" que es justo el tercer campo del struct de una constante y es el que ponemos en tercer lugar en su asignación, como podemos ver en
Quote from: main_core.c
static struct
{
   char * name ;
   int    type ;
   int    code ;
}
constants_def[] =
...
Ahora bien, esta es la que usa el nucleo para insertar en el array de constantes la constante en cuestión, pero luego al pasarlo al array de constantes veo que la estructura es otra
Quote from: constants.h
typedef struct _constant
{
   int      code ;
   int      value ;
   TYPEDEF type ;
}
CONSTANT ;

extern void constants_init () ;
extern void constants_dump () ;
extern void constants_add (int code, TYPEDEF type, int value) ;
extern CONSTANT * constants_search (int code) ;
De esta estructura puedo deducir que actualmente bennu solo permite constantes de tipo "int" de C. (Bueno, haciendo piñuelas podremos meter cualquier cosa que no supere el tamaño de un int de C)
Así que tanto si pones type_dword como type_int a bennu le da igual y lo asigna a un int. También deduzco que si un int tiene capacidad para almacenar un dword como mínimo para compilar bennu debemos estar en máquinas de 32 bits :D. (byte = 8, word = 16, dword = 32).

Todo esto referente a constantes.
Ahora tengo una pregunta acerca de las globales, veo que siempres pones los últimos campos a NULL,-1,-1.
como por ejemplo en:
Quote from: libscroll.c
DLVARFIXUP __bgdexport( libscroll, globals_fixup )[] =
{
   /* Nombre de variable global, puntero al dato, tamaño del elemento, cantidad de elementos */
   { "scroll" , NULL, -1, -1 },
   { NULL , NULL, -1, -1 }
};
Supongo que así es para decirle que calcule internamente los valores, pero ¿como se utilizarían manualmente?
puntero al dato: esto que sería a un dato creado dinámicamente en c?
tamaño del elemento: esto que seria el tamaño del dato en bytes?
cantidad de elementos: ya con esto me matas :) esto qué es, por si es un array lo que te inserto?
Venga, saludos, y gracias de antemano.

EDIT: Lo de las macros que comentas que no hay para floats ya he visto que es para globals y locals.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

DCelso

tooma geroma pastillas de goma, le inserté un valor en módulo 2 en hexadecimal al dato constante y se lo ha tragado com papas Bennu.
Juas, juas, he insertado un float en un int, que bueno soy. Gracias a que ambos datos ocupan los mismos bytes en memoria que si noo.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

vamos por partes...

1) el index que mencionaba no es para las constantes, es para los FIXUPS y usarlos luego con los LOC* o GLO*... cuando dije "declaras constantes que son para el orden... blah..." me referia a constantes C (#define), no me referia a constantes Bennu... disculpas por no haber sido mas claro...
2) ahora que lo miro bien, las constantes solo pueden ser enteras.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

Bueno, ya no es problema, ya se como meter floats como constantes. Pasas el valor del float a hexadecimal y lo insertas como 0x"valor".

Lo que me he encontrado es con un problema, creo que más gordo. Las funciones solo devuelven enteros.


function devolver_floats()
private
     float retorno;
begin
    retorno = 6.39;
    return retorno;
end
begin
  say(devolver_floats());
end

En la pantalla aparece 6

Lo he solvetado con la siguiente triquiñuela

local
   float mi_float;
end
function devolver_floats(float * retorno)
begin
    *retorno = 6.39;
    return *retorno;
end
begin
  devolver_floats(&mi_float);
  say(mi_float);
end

esto pone en pantalla 6.39.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

osk

Bueno, esto no creo que sea un problema.
Es que es así...C es así.
Si quieres devolver otro tipo de valores, tienes que usar parámetros pasados por referencia (es decir, punteros).

DCelso

C que va a ser así, en c puedes devolver de todo, hasta estructuras completas si quieres;

typedef struct st_mi_estructura_compleja{
   int dato1;
   char dato2;
   float dato3;
   double dato4;
   int * puntero;
}tst_mi_estructura_compleja;

tst_mi_estructura_compleja unafuncion_que_devuelve_estructuras_complejas(int parametro_entrada_1)
{
  tst_mi_estructura_compleja st_de_retorno;
  st_de_retorno.dato1 =parametro_entrada_1;
  st_de_retorno.dato2 = 'a';
  st_de_retorno.dato3 = 3.0;
  st_de_retorno.dato4 = 5.0;
  st_de_retorno.puntero =0;
  return st_de_retorno;
}
int main(int argc, char*argv[])
{
   st_mi_estructura_compleja misdatos;
   misdatos=unafuncion_que_devuelve_estructuras_complejas(100);
   printf("dato1: %d\n",misdatos.dato1);
   printf("dato2: %c\n",misdatos.dato2);
   printf("dato3: %f\n",misdatos.dato3);
   printf("dato4: %f\n",misdatos.dato4);
   printf("puntero: %p\n",misdatos.puntero);
}
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

DCelso

Creo que te has liado con lo que no puede devolver más de un dato, ni pasar parámetros por referencia, esto es lo que se simula con los punteros.
Pero ya en c++ suplieron lo de los parámetros por referencia.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

Quote from: DCelso on February 25, 2010, 11:00:37 PM
Bueno, ya no es problema, ya se como meter floats como constantes. Pasas el valor del float a hexadecimal y lo insertas como 0x"valor".

Lo que me he encontrado es con un problema, creo que más gordo. Las funciones solo devuelven enteros.


function devolver_floats()
private
     float retorno;
begin
    retorno = 6.39;
    return retorno;
end
begin
  say(devolver_floats());
end

En la pantalla aparece 6

Lo he solvetado con la siguiente triquiñuela

local
   float mi_float;
end
function devolver_floats(float * retorno)
begin
    *retorno = 6.39;
    return *retorno;
end
begin
  devolver_floats(&mi_float);
  say(mi_float);
end

esto pone en pantalla 6.39.


1) eso de ponerlo como hexa funciona, pero no es lo adecuado... cuando en algun tiempo lo quieras tocar o lo quiera seguir algun otro no va a saber que quisiste poner...

2) si declaras la funcion como float (y antes de su uso) funcionara... (ya fue dicho muchas veces esto...)

Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

¿Como se declara una función como float?
Antes de preguntarlo busqué por el foro y wiki todo acerca de functions y no encontré nada.
Si nos lo cuentas, lo insertaré en la wiki.
Voy a buscar de nuevo a ver si ahora sabiendo a ciencia cierta que hay algo lo encuentro :D.

Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

:P


function float devolver_floats()
begin
    return 6.39;
end


admiti que fue una pregunta tonta...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2