diff --git a/ediv/doc/html/varindex-howto.dok b/ediv/doc/html/varindex-howto.dok new file mode 100644 index 0000000..ec61286 --- /dev/null +++ b/ediv/doc/html/varindex-howto.dok @@ -0,0 +1,92 @@ +<%title%>Uso del indexado dinámico de variables desde el stub y las librerías<%/title%> +

Uso del indexado dinámico de variables desde el stub y las librerías

+

Mediante el indexado dinámico podemos acceder a cualquier variable, + tabla o estructura situada en cualquier librería. Para este fin existe + una función, GetVarOffset, que devuelve el offset en mem[] + de cualquier variable indicando su tipo (global, reserved, local) y su nombre + como cadena de caracteres. Sin embargo, para simplificar la tarea, existen unas + macros cuyo uso voy a explicar aquí.

+

Macros de acceso directo a variables

+

Mediante estas macros podemos acceder a las variables de DIV como si de variables + del lenguaje C se trataran. Podemos usarlas en expresiones, asignarles valores + y obtener su offset con el operador &.

+

global ("nombre")

+

Accede directamente a la variable global indicada.

+

Ejemplo:

+<%code%>if ( global("dump_type") == 0 ) ...<%/code%> +

reserved ("nombre", id)

+

Accede directamente a la variable de la estructura reserved del + proceso indicado.

+

Ejemplo:

+<%code%>reserved("frame_percent",id) += mem[imem++];<%/code%> +

local ("nombre", id)

+

Accede directamente a la variable local del proceso indicado.

+

Ejemplo:

+<%code%>if ( local("graph",id) != 0 ) ...<%/code%> +

Macros de offset relativo a mem[]

+

El objetivo de estas macros es obtener el offset relativo a mem[] + de la variable deseada. Generalmente no será necesario usarlas, excepto + para acceder a tablas y estructuras.

+

globalptr ("nombre")

+

Obtiene el offset en mem[] de la variable global indicada.

+

Ejemplo:

+<%code%>mem[globalptr("fps")] = my_fps;<%/code%> +

reservedptr ("nombre")

+

Obtiene el offset en mem[] relativo a proceso (sin sumar + el id) de la variable indicada de la estructura reserved.

+

Ejemplo:

+<%code%>mem[reservedptr("status") + id] = 4;<%/code%> +

localptr ("nombre")

+

Obtiene el offset en mem[] relativo a proceso (sin sumar + el id) de la variable local.

+

Ejemplo:

+<%code%>mem[localptr("size") + id] = 100;<%/code%> + +

Cómo acceder a tablas y estructuras

+
+
    +
  1. Tablas +

    Es muy sencillo: con globalptr o localptr obtenemos + el offset del comienzo de la tabla. Luego basta sumar a ese offset el número + de posición de la tabla que queremos leer o escribir.

    +

    Ejemplo: Para poner timer[4] a cero:

    + <%code%> + mem[globalptr("timer") + 4] = 0; + <%/code%> +

     

    +
  2. +
  3. Estructuras +

    Aquí la cosa es parecida. Empecemos con una estructura de 1 sólo + registro, por ejemplo mouse. Supongamos que queremos acceder + a su miembro left. Con globalptr obtenemos el + offset del inicio de la estructura. Después debemos sumarle la posición + en la que se encuentra el miembro dentro de la estructura, empezando a contar + por 0 (o, dicho de otro modo, el número de miembros que preceden + a la estructura). En este caso, a left le corresponde el número + 9. Así, para poner mouse.left a 1:

    + <%code%> + mem[globalptr("mouse") + 9] = 1; + <%/code%> +

    ¡OJO! Hemos dado por supuesto que todos los miembros + son int. Si la estructura contiene alguna tabla, debemos sumar + el tamaño de la tabla en int's. Si contiene una string, + debemos sumar su tamaño en int's, que se calcula así: + 1+(tamaño+5)/4.

    +

    En el caso de que la estructura tenga varios registros, hay que sumar al + offset, además de la posición del miembro en cuestión, + el tamaño de la estructura multiplicado por el número del + registro. Por ejemplo, para acceder a scroll[3].z:

    + <%code%> + my_z = mem[globalptr("scroll") + 4 + 10 * 3]; + <%/code%> +

    El 4 es la posición de z en la estructura, y el 10 + el tamaño de la estructura scroll.

    + +

    Naturalmente, si queremos acceder a una estructura local, en el caso de + que la haya (no hace falta usar este método para acceder a variables + de reserved ya que para eso está la macro reserved + explicada más arriba), también habrá que sumar al offset + el id del proceso.

    +
  4. +
+<%end%> diff --git a/ediv/src/stub/varindex.c b/ediv/src/stub/varindex.c new file mode 100644 index 0000000..b3d539a --- /dev/null +++ b/ediv/src/stub/varindex.c @@ -0,0 +1,69 @@ +/* + * eDiv Executable Stub + * Copyleft (C) 2000-2002 Sion Ltd. + * http://www.sionhq.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "main.h" +#include "varindex.h" + +int GetVarOffset(tipo_t tipo, char* nombre) +{ + byte *c, h=0; + int bajo, alto, medio, ok=0; + + for(c=(byte*)nombre;*c;c++) + h=((byte)(h<<1)+(h>>7))^*c; + + bajo=0; + alto=num_indexed_vars-1; + + while(bajo<=alto) { + medio=(bajo+alto)/2; + if(hvarindex[medio].hash) bajo=medio+1; + else { ok=1; break; } + } + + if(!ok) { + #ifdef _DEBUG + printf("varindex: GetVarOffset: Hash %d no encontrado (%s %s)\n", + h,tipo==v_global?"global":tipo==v_reserved?"reserved":"local",nombre); + #endif + return 0; + } + + if(medio>0) while(varindex[medio-1].hash==h) if(--medio==0) break; + + while(varindex[medio].hash==h) { + if(varindex[medio].tipo==tipo) { + if(!strcmp(varindex[medio].nombre,nombre)) { + return varindex[medio].offset; + } + } + medio++; + } + + #ifdef _DEBUG + printf("varindex: GetVarOffset: Nombre no encontrado (%s %s) hash=%d\n", + tipo==v_global?"global":tipo==v_reserved?"reserved":"local",nombre,h); + #endif + return 0; +}