indexado dinamico
This commit is contained in:
parent
042fcd7297
commit
386186ee5c
92
ediv/doc/html/varindex-howto.dok
Normal file
92
ediv/doc/html/varindex-howto.dok
Normal file
|
@ -0,0 +1,92 @@
|
|||
<%title%>Uso del indexado dinámico de variables desde el <i>stub</i> y las librerías<%/title%>
|
||||
<h1>Uso del indexado dinámico de variables desde el <i>stub</i> y las librerías</h1>
|
||||
<p> 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 <code>mem[]</code>
|
||||
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í.</p>
|
||||
<h2>Macros de acceso directo a variables</h2>
|
||||
<p>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 &.</p>
|
||||
<h3>global ("<em>nombre</em>")</h3>
|
||||
<p>Accede directamente a la variable global indicada.</p>
|
||||
<p>Ejemplo:</p>
|
||||
<%code%>if ( global("dump_type") == 0 ) ...<%/code%>
|
||||
<h3>reserved ("<em>nombre</em>",<em> id</em>)</h3>
|
||||
<p>Accede directamente a la variable de la estructura <code>reserved</code> del
|
||||
proceso indicado.</p>
|
||||
<p>Ejemplo:</p>
|
||||
<%code%>reserved("frame_percent",id) += mem[imem++];<%/code%>
|
||||
<h3>local ("<em>nombre</em>", <em>id</em>)</h3>
|
||||
<p>Accede directamente a la variable local del proceso indicado.</p>
|
||||
<p>Ejemplo:</p>
|
||||
<%code%>if ( local("graph",id) != 0 ) ...<%/code%>
|
||||
<h2>Macros de offset relativo a <code>mem[]</code></h2>
|
||||
<p>El objetivo de estas macros es obtener el offset relativo a <code>mem[]</code>
|
||||
de la variable deseada. Generalmente no será necesario usarlas, excepto
|
||||
para <a href="#structabl">acceder a tablas y estructuras</a>.</p>
|
||||
<h3>globalptr ("<em>nombre</em>")</h3>
|
||||
<p>Obtiene el offset en <code>mem[]</code> de la variable global indicada.</p>
|
||||
<p>Ejemplo:</p>
|
||||
<%code%>mem[globalptr("fps")] = my_fps;<%/code%>
|
||||
<h3>reservedptr ("<em>nombre</em>")</h3>
|
||||
<p>Obtiene el offset en <code>mem[]</code> relativo a proceso (<strong>sin sumar
|
||||
el id</strong>) de la variable indicada de la estructura <code>reserved</code>.</p>
|
||||
<p>Ejemplo:</p>
|
||||
<%code%>mem[reservedptr("status") + id] = 4;<%/code%>
|
||||
<h3>localptr ("<em>nombre</em>")</h3>
|
||||
<p>Obtiene el offset en <code>mem[]</code> relativo a proceso (<strong>sin sumar
|
||||
el id</strong>) de la variable local.</p>
|
||||
<p>Ejemplo:</p>
|
||||
<%code%>mem[localptr("size") + id] = 100;<%/code%>
|
||||
<a name="structabl">
|
||||
<h2>Cómo acceder a tablas y estructuras</h2>
|
||||
</a>
|
||||
<ol type="I">
|
||||
<li>Tablas
|
||||
<p>Es muy sencillo: con <code>globalptr</code> o <code>localptr</code> 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.</p>
|
||||
<p>Ejemplo: Para poner <code>timer[4]</code> a cero:</p>
|
||||
<%code%>
|
||||
mem[globalptr("timer") + 4] = 0;
|
||||
<%/code%>
|
||||
<p> </p>
|
||||
</li>
|
||||
<li>Estructuras
|
||||
<p>Aquí la cosa es parecida. Empecemos con una estructura de 1 sólo
|
||||
registro, por ejemplo <code>mouse</code>. Supongamos que queremos acceder
|
||||
a su miembro <code>left</code>. Con <code>globalptr</code> 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 <code>left</code> le corresponde el número
|
||||
9. Así, para poner <code>mouse.left</code> a 1:</p>
|
||||
<%code%>
|
||||
mem[globalptr("mouse") + 9] = 1;
|
||||
<%/code%>
|
||||
<p><strong>¡OJO!</strong> Hemos dado por supuesto que todos los miembros
|
||||
son <code>int</code>. Si la estructura contiene alguna tabla, debemos sumar
|
||||
el tamaño de la tabla en <em>int's</em>. Si contiene una <code>string</code>,
|
||||
debemos sumar su tamaño en <em>int's</em>, que se calcula así:
|
||||
1+(tamaño+5)/4.</p>
|
||||
<p>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 <code>scroll[3].z</code>:</p>
|
||||
<%code%>
|
||||
my_z = mem[globalptr("scroll") + 4 + 10 * 3];
|
||||
<%/code%>
|
||||
<p>El 4 es la posición de <code>z</code> en la estructura, y el 10
|
||||
el tamaño de la estructura <code>scroll</code>.</p>
|
||||
|
||||
<p>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 <code>reserved</code> ya que para eso está la macro <code>reserved</code>
|
||||
explicada más arriba), también habrá que sumar al offset
|
||||
el id del proceso.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<%end%>
|
69
ediv/src/stub/varindex.c
Normal file
69
ediv/src/stub/varindex.c
Normal file
|
@ -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 <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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(h<varindex[medio].hash) alto=medio-1;
|
||||
else if(h>varindex[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;
|
||||
}
|
Loading…
Reference in a new issue