Index: parser.c
===================================================================
--- parser.c	(revision 135)
+++ parser.c	(revision 136)
@@ -148,3 +148,99 @@
 return RAYDIUM_PARSER_TYPE_FLOAT;    
 
 }
+
+signed char raydium_parser_db_get(char *key, char *value, char *def)
+{
+FILE *fp;
+char line[(RAYDIUM_MAX_NAME_LEN*2)+1];
+char part1[RAYDIUM_MAX_NAME_LEN];
+char part2[RAYDIUM_MAX_NAME_LEN];
+signed char found=0;
+
+fp=fopen(RAYDIUM_DB_FILENAME,"rt");
+
+while( fp && (fgets(line,RAYDIUM_MAX_NAME_LEN,fp)) )
+    {
+    raydium_parser_trim(line);
+    if(!raydium_parser_cut(line,part1,part2,RAYDIUM_DB_SEPARATOR))
+	{
+	raydium_log("db: ERROR: invalid: '%s'",line);
+	continue;
+	}
+
+    if(strcmp(part1,key))
+	continue;
+
+    found=1;
+    strcpy(value,part2);
+    }
+
+if(fp)
+    fclose(fp);
+
+if(!found && def)
+    {
+    strcpy(value,def);
+    found=1;
+    }
+
+return found;
+}
+
+
+signed char raydium_parser_db_set(char *key, char *value)
+{
+FILE *fp,*out;
+char line[(RAYDIUM_MAX_NAME_LEN*2)+1];
+char part1[RAYDIUM_MAX_NAME_LEN];
+char part2[RAYDIUM_MAX_NAME_LEN];
+signed char found=0;
+
+out=fopen(RAYDIUM_DB_TEMP,"wt");
+
+if(!out)
+    {
+    raydium_log("db: cannot create new database !");
+    return 0;
+    }
+
+
+fp=fopen(RAYDIUM_DB_FILENAME,"rt");
+
+
+while( fp && (fgets(line,RAYDIUM_MAX_NAME_LEN,fp)) )
+    {
+    raydium_parser_trim(line);
+
+    if(!raydium_parser_cut(line,part1,part2,RAYDIUM_DB_SEPARATOR))
+	{
+	raydium_log("db: ERROR: invalid: '%s'",line);
+	continue;
+	}
+
+    if(!strcmp(part1,key))
+	{
+	fprintf(out,"%s;%s\n",key,value);
+	found=1;
+	continue;
+	}
+
+    fprintf(out,"%s\n",line);
+    }
+
+if(!found)
+    fprintf(out,"%s;%s\n",key,value);
+
+if(fp)
+    fclose(fp);
+fclose(out);
+
+if(rename(RAYDIUM_DB_TEMP,RAYDIUM_DB_FILENAME)==-1)
+    {
+    raydium_log("db: cannot rename new database !");
+    perror("rename");
+    return 0;
+    }
+
+return 1;
+}
ag);
        return -1;
        }

    free(str_vert);
    free(str_frag);

    raydium_shader_shaders[i].prog=glCreateProgramObjectARB();
    glAttachObjectARB(raydium_shader_shaders[i].prog,raydium_shader_shaders[i].vert);
    glAttachObjectARB(raydium_shader_shaders[i].prog,raydium_shader_shaders[i].frag);

    glLinkProgramARB(raydium_shader_shaders[i].prog);
    glGetObjectParameterivARB(raydium_shader_shaders[i].prog,GL_OBJECT_LINK_STATUS_ARB,&ret);
    if(ret!=1)
        {
        raydium_log("shader: '%s': Linking FAILED",name);
        raydium_shader_infolog(raydium_shader_shaders[i].prog);
        glDeleteObjectARB(raydium_shader_shaders[i].vert);
        glDeleteObjectARB(raydium_shader_shaders[i].frag);
        glDeleteObjectARB(raydium_shader_shaders[i].prog);
        return -1;
        }

    curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
    glUseProgramObjectARB(raydium_shader_shaders[i].prog);
    raydium_shader_shaders[i].attrib_tangent=glGetAttribLocationARB(
                                             raydium_shader_shaders[i].prog,
                                             RAYDIUM_SHADER_TANGENT_ATTRIB_NAME);
    glUseProgramObjectARB(curr);

    raydium_shader_shaders[i].state=1;
    strcpy(raydium_shader_shaders[i].name,name);
    raydium_log("shader: shader %i (%s) loaded (%s,%s%s)",
                i,name,file_vert,file_frag,
                ((raydium_shader_shaders[i].attrib_tangent==-1)?"":",tangent"));
    return i;
    }

raydium_log("shader: Error: No more slots ! aborting \"%s\" creation",name);
return -1;
}

signed char raydium_shader_delete(int shader)
{
int i;

if(!raydium_shader_support)
    return 0;

if(!raydium_shader_isvalid(shader))
    {
    raydium_log("shader: cannot delete: Invalid shader index or name");
    return 0;
    }

glDetachObjectARB(raydium_shader_shaders[shader].prog,raydium_shader_shaders[shader].vert);
glDeleteObjectARB(raydium_shader_shaders[shader].vert);
glDetachObjectARB(raydium_shader_shaders[shader].prog,raydium_shader_shaders[shader].frag);
glDeleteObjectARB(raydium_shader_shaders[shader].frag);
glDeleteObjectARB(raydium_shader_shaders[shader].prog);
raydium_shader_shaders[shader].state=0;

// detach from texture
for(i=1;i<RAYDIUM_MAX_TEXTURES;i++)
    if(raydium_texture_used[i] && raydium_texture_shader[i]==shader)
        raydium_texture_shader[i]=-1;

return 1;
}

void raydium_shader_delete_all(void)
{
int i;

for(i=0;i<RAYDIUM_MAX_SHADERS;i++)
    if(raydium_shader_shaders[i].state)
        raydium_shader_delete(i);
}

int raydium_shader_variable(int shader, char *name)
{
int ret;

if(!raydium_shader_support)
    return -1;

if(!raydium_shader_isvalid(shader))
    {
    raydium_log("shader: cannot get variable: Invalid shader index or name");
    return -1;
    }

ret=glGetUniformLocationARB(raydium_shader_shaders[shader].prog,name);
if(ret<0)
    {
    raydium_log("shader: cannot get variable: Invalid variable name '%s'",name);
    return -1;
    }
return ret;
}

signed char raydium_shader_var_i(int var_id, int value)
{
if(!raydium_shader_support)
    return 0;

glUniform1iARB(var_id,value);
return 1;
}

signed char raydium_shader_var_i_name(char *shader, char *variable, int value)
{
signed char ret;
GLhandleARB curr;
int sid;

if(!raydium_shader_support)
    return 0;

curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
sid=raydium_shader_find(shader);
raydium_shader_current(sid);
ret=raydium_shader_var_i(raydium_shader_variable(sid,variable),value);
glUseProgramObjectARB(curr);
return ret;
}

signed char raydium_shader_var_fv(int var_id, int num,float value[])
{
if(!raydium_shader_support)
    return 0;

glUniform1fvARB(var_id,num,value);
return 1;
}

signed char raydium_shader_var_fv_name(char *shader, char *variable, int num, float value[])
{
signed char ret;
GLhandleARB curr;
int sid;

if(!raydium_shader_support)
    return 0;

curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
sid=raydium_shader_find(shader);
raydium_shader_current(sid);
ret=raydium_shader_var_fv(raydium_shader_variable(sid,variable),num,value);
glUseProgramObjectARB(curr);
return ret;
}

signed char raydium_shader_var_matrix4fv(int var_id, int num,int transpose,float value[])
{
if(!raydium_shader_support)
    return 0;

glUniformMatrix4fvARB(var_id,num,transpose,value);
return 1;
}

signed char raydium_shader_var_matrix4fv_name(char *shader, char *variable, int num, int transpose, float value[])
{
signed char ret;
GLhandleARB curr;
int sid;

if(!raydium_shader_support)
    return 0;

curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
sid=raydium_shader_find(shader);
raydium_shader_current(sid);
ret=raydium_shader_var_matrix4fv(raydium_shader_variable(sid,variable),num,transpose,value);
glUseProgramObjectARB(curr);
return ret;
}

signed char raydium_shader_var_f(int var_id, float value)
{
if(!raydium_shader_support)
    return 0;

glUniform1fARB(var_id,value);
return 1;
}

signed char raydium_shader_var_f_name(char *shader, char *variable, float value)
{
signed char ret;
GLhandleARB curr;
int sid;

if(!raydium_shader_support)
    return 0;

curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
sid=raydium_shader_find(shader);
raydium_shader_current(sid);
ret=raydium_shader_var_f(raydium_shader_variable(sid,variable),value);
glUseProgramObjectARB(curr);
return ret;
}

signed char raydium_shader_var_2f(int var_id, float value1, float value2)
{
if(!raydium_shader_support)
    return 0;

glUniform2fARB(var_id,value1,value2);
return 1;
}

signed char raydium_shader_var_2f_name(char *shader, char *variable, float value1, float value2)
{
signed char ret;
GLhandleARB curr;
int sid;

if(!raydium_shader_support)
    return 0;

curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
sid=raydium_shader_find(shader);
raydium_shader_current(sid);
ret=raydium_shader_var_2f(raydium_shader_variable(sid,variable),value1,value2);
glUseProgramObjectARB(curr);
return ret;
}

signed char raydium_shader_var_3f(int var_id, float value1, float value2, float value3)
{
if(!raydium_shader_support)
    return 0;

glUniform3fARB(var_id,value1,value2,value3);
return 1;
}

signed char raydium_shader_var_3f_name(char *shader, char *variable, float value1, float value2, float value3)
{
signed char ret;
GLhandleARB curr;
int sid;

if(!raydium_shader_support)
    return 0;

curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
sid=raydium_shader_find(shader);
raydium_shader_current(sid);
ret=raydium_shader_var_3f(raydium_shader_variable(sid,variable),value1,value2,value3);
glUseProgramObjectARB(curr);
return ret;
}

signed char raydium_shader_var_4f(int var_id, float value1, float value2, float value3, float value4)
{
if(!raydium_shader_support)
    return 0;

glUniform4fARB(var_id,value1,value2,value3,value4);
return 1;
}

signed char raydium_shader_var_4f_name(char *shader, char *variable, float value1, float value2, float value3, float value4)
{
signed char ret;
GLhandleARB curr;
int sid;

if(!raydium_shader_support)
    return 0;

curr=glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
sid=raydium_shader_find(shader);
raydium_shader_current(sid);
ret=raydium_shader_var_4f(raydium_shader_variable(sid,variable),value1,value2,value3,value4);
glUseProgramObjectARB(curr);
return ret;
}


// -1 = off
signed char raydium_shader_current(int shader)
{
if(!raydium_shader_support)
    return 0;

raydium_shader_active=shader;

if(shader==-1)
    {
    glUseProgramObjectARB(0);
    return 1;
    }

if(!raydium_shader_isvalid(shader))
    {
    raydium_log("shader: cannot use shader: Invalid index or name");
    return 0;
    }

glUseProgramObjectARB(raydium_shader_shaders[shader].prog);
return 1;
}

signed char raydium_shader_current_name(char *shader)
{
return raydium_shader_current(raydium_shader_find(shader));
}

signed char raydium_shader_attach_texture(int shader, int texture)
{
if(shader!=-1 && !raydium_shader_isvalid(shader)) // -1 to disable shader
    {
    raydium_log("shader: cannot attach shader: Invalid shader");
    return 0;
    }
//if(texture<=0 || texture>=(int)raydium_texture_index)
if(!raydium_texture_is_slot_used(texture))
    {
    raydium_log("shader: cannot attach shader: Invalid texture");
    return 0;
    }
raydium_texture_shader[texture]=shader;
return 1;
}

signed char raydium_shader_attach_texture_name(char *shader, char *texture)
{
return raydium_shader_attach_texture(raydium_shader_find(shader),
                                     raydium_texture_find_by_name(texture));
}

void raydium_shader_internal_vertex_attributes(int i)
{
// shader with "tangent" attribute active ?
if(raydium_shader_support && raydium_shader_active>=0 &&
   raydium_shader_shaders[raydium_shader_active].attrib_tangent!=-1)
    {
     glVertexAttrib3fARB(raydium_shader_shaders[raydium_shader_active].attrib_tangent,
                         raydium_vertex_tangent_x(i),
                         raydium_vertex_tangent_y(i),
                         raydium_vertex_tangent_z(i));
     //printf("%f %f %f\n",raydium_vertex_tangent_x[i],raydium_vertex_tangent_y[i],raydium_vertex_tangent_z[i]);
    }
}