added support for glGetIntegerv
authorEleni Maria Stea <elene.mst@gmail.com>
Wed, 13 Feb 2013 16:01:32 +0000 (18:01 +0200)
committerEleni Maria Stea <elene.mst@gmail.com>
Wed, 13 Feb 2013 16:01:32 +0000 (18:01 +0200)
changed the design to support glGet functions with indices like glGetStringi

gliar.conf
src/cfg.c
src/cfg.h
src/gliar.c

index b65b379..2082d0e 100644 (file)
@@ -3,6 +3,7 @@ Mutant Stargoat
 
 [extensions]
 GL_MSG_hikiko_ext
 
 [extensions]
 GL_MSG_hikiko_ext
+GL_ARB_multitexture
 GL_MSG_test
 
 [renderer]
 GL_MSG_test
 
 [renderer]
@@ -10,3 +11,9 @@ fake_mesa
 
 [sl version]
 fake_sl
 
 [sl version]
 fake_sl
+
+[max texture units]
+2
+
+[max texture size]
+2048
index 50c4f9c..c721ecb 100644 (file)
--- a/src/cfg.c
+++ b/src/cfg.c
@@ -29,12 +29,54 @@ Author: Eleni Maria Stea <elene.mst@gmail.com>
 static char *stripspace(char *s);
 static void concat_values(struct cfgopt *opt);
 
 static char *stripspace(char *s);
 static void concat_values(struct cfgopt *opt);
 
+/* linked list of valid value filters */
+static struct cfgopt *valid_vals;
+
+/* adds a new filter set of valid values for the key "key" */
+void gliar_value_set(const char *key, char **valid, int vcount)
+{
+       int i;
+       struct cfgopt *node;
+
+       if(!(node = malloc(sizeof *node))) {
+               return;
+       }
+       if(!(node->key = malloc(strlen(key) + 1))) {
+               free(node);
+               return;
+       }
+       strcpy(node->key, key);
+
+       if(!(node->str_val = malloc(vcount * sizeof *node->str_val))) {
+               free(node->key);
+               free(node);
+               return;
+       }
+       for(i=0; i<vcount; i++) {
+               if(!(node->str_val[i] = malloc(strlen(valid[i]) + 1))) {
+                       for(; i>=0; i--) {
+                               free(node->str_val[i]);
+                               free(node->key);
+                               free(node);
+                               return;
+                       }
+               }
+               strcpy(node->str_val[i], valid[i]);
+       }
+
+       node->str_count = vcount;
+
+       node->next = valid_vals;
+       valid_vals = node;
+}
+
 struct cfgopt *gliar_load_cfg(const char *fname)
 {
        FILE *fp;
        char buf[512];
        struct cfgopt *optlist = 0;
        struct cfgopt *opt = 0;
 struct cfgopt *gliar_load_cfg(const char *fname)
 {
        FILE *fp;
        char buf[512];
        struct cfgopt *optlist = 0;
        struct cfgopt *opt = 0;
+       const struct cfgopt *filter;
 
        if(!(fp = fopen(fname, "r"))) {
                return 0;
 
        if(!(fp = fopen(fname, "r"))) {
                return 0;
@@ -48,6 +90,7 @@ struct cfgopt *gliar_load_cfg(const char *fname)
                }
 
                if(*line == '[') {
                }
 
                if(*line == '[') {
+                       /* found a new key */
                        char *end = strrchr(line, ']');
                        if(!end) {
                                fprintf(stderr, "invalid config %s: %s\n", fname, line);
                        char *end = strrchr(line, ']');
                        if(!end) {
                                fprintf(stderr, "invalid config %s: %s\n", fname, line);
@@ -62,6 +105,9 @@ struct cfgopt *gliar_load_cfg(const char *fname)
                                concat_values(opt);
                        }
 
                                concat_values(opt);
                        }
 
+                       /* find the valid values for this particular key (if any) */
+                       filter = gliar_find_opt(valid_vals, line);
+
                        if((opt = malloc(sizeof *opt))) {
                                if((opt->key = malloc(strlen(line) + 1))) {
                                        strcpy(opt->key, line);
                        if((opt = malloc(sizeof *opt))) {
                                if((opt->key = malloc(strlen(line) + 1))) {
                                        strcpy(opt->key, line);
@@ -75,14 +121,28 @@ struct cfgopt *gliar_load_cfg(const char *fname)
                                }
                        }
                } else {
                                }
                        }
                } else {
-                       int new_sz = opt->str_count + 1;
+                       /* found a value for the current key (opt->key) */
+                       int i, num, new_sz = opt->str_count + 1;
                        char **tmp;
                        char **tmp;
-
                        char *end;
                        char *end;
-                       int num = strtol(line, &end, 10);
 
 
+                       if(filter) {
+                               for(i=0; i<filter->str_count; i++) {
+                                       if(strcmp(line, filter->str_val[i]) == 0) {
+                                               break;
+                                       }
+                               }
+
+                               if(i == filter->str_count) {
+                                       /* the string is not in the valid list, ignore it */
+                                       fprintf(stderr, "GLIAR: extension %s not supported, ignoring\n", line);
+                                       continue;
+                               }
+                       }
+
+                       num = strtol(line, &end, 10);
                        if(!*end) {
                        if(!*end) {
-                               opt->num_val = line;
+                               opt->num_val = num;
                                opt->type = GLIAR_NUMBER;
                        }
 
                                opt->type = GLIAR_NUMBER;
                        }
 
@@ -159,6 +219,11 @@ static void concat_values(struct cfgopt *opt)
        int i;
        int sz = opt->str_count - 1;
 
        int i;
        int sz = opt->str_count - 1;
 
+       if(!opt->str_count) {
+               opt->conc_vals = 0;
+               return;
+       }
+
        for(i=0; i<opt->str_count; i++) {
                sz += strlen(opt->str_val[i]);
        }
        for(i=0; i<opt->str_count; i++) {
                sz += strlen(opt->str_val[i]);
        }
index c665782..c009c95 100644 (file)
--- a/src/cfg.h
+++ b/src/cfg.h
@@ -38,6 +38,8 @@ struct cfgopt {
        struct cfgopt *next;
 };
 
        struct cfgopt *next;
 };
 
+void gliar_value_set(const char *key, char **valid, int vcount);
+
 struct cfgopt *gliar_load_cfg(const char *fname);
 
 const struct cfgopt *gliar_find_opt(struct cfgopt *list, const char *name);
 struct cfgopt *gliar_load_cfg(const char *fname);
 
 const struct cfgopt *gliar_find_opt(struct cfgopt *list, const char *name);
index 1173a43..5fe944d 100644 (file)
@@ -23,21 +23,28 @@ Author: Eleni Maria Stea <elene.mst@gmail.com>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <unistd.h>
 #include <dlfcn.h>
 #include <pwd.h>
 #include <GL/gl.h>
 #include "cfg.h"
 
 #include <unistd.h>
 #include <dlfcn.h>
 #include <pwd.h>
 #include <GL/gl.h>
 #include "cfg.h"
 
+#ifndef GL_NUM_SHADING_LANGUAGE_VERSIONS
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS       0x82E9
+#endif
+
+static int init_valid_extensions(void);
+
 static int done_init;
 
 static const GLubyte* (*gl_get_string)(GLenum);
 static int done_init;
 
 static const GLubyte* (*gl_get_string)(GLenum);
-/*static const GLubyte* (*gl_get_stringi)(GLenum, GLuint);
+static const GLubyte* (*gl_get_stringi)(GLenum, GLuint);
+static const void* (*gl_get_integerv)(GLenum, GLint*);
 
 
-static const void* (*gl_get_booleanv)(GLenum, GLboolean*);
+/*static const void* (*gl_get_booleanv)(GLenum, GLboolean*);
 static const void* (*gl_get_doublev)(GLenum, GLdouble*);
 static const void* (*gl_get_floatv)(GLenum, GLfloat*);
 static const void* (*gl_get_doublev)(GLenum, GLdouble*);
 static const void* (*gl_get_floatv)(GLenum, GLfloat*);
-static const void* (*gl_get_integerv)(GLenum, GLint*);
 static const void* (*gl_get_integer64v)(GLenum, GLint64*);
 
 static const void* (*gl_get_booleani_v)(GLenum, GLuint, GLboolean*);
 static const void* (*gl_get_integer64v)(GLenum, GLint64*);
 
 static const void* (*gl_get_booleani_v)(GLenum, GLuint, GLboolean*);
@@ -48,12 +55,32 @@ static const void* (*gl_get_integer64i_v)(GLenum, GLuint, GLint64*);*/
 
 static struct cfgopt *cfglist;
 
 
 static struct cfgopt *cfglist;
 
+
 static int init(void)
 {
        if(done_init) {
                return 0;
        }
 
 static int init(void)
 {
        if(done_init) {
                return 0;
        }
 
+       gl_get_string = dlsym(RTLD_NEXT, "glGetString");
+       gl_get_stringi = dlsym(RTLD_NEXT, "glGetStringi");
+       gl_get_integerv = dlsym(RTLD_NEXT, "glGetIntegerv");
+
+       /*gl_get_booleanv = dlsym(RTLD_NEXT, "glGetBooleanv");
+       gl_get_doublev = dlsym(RTLD_NEXT, "glGetDoublev");
+       gl_get_floatv = dlsym(RTLD_NEXT, "glGetFloatv");
+       gl_get_integer64v = dlsym(RTLD_NEXT, "glGetInteger64v");
+
+       gl_get_booleani_v = dlsym(RTLD_NEXT, "glGetBooleani_v");
+       gl_get_doublei_v = dlsym(RTLD_NEXT, "glGetDoublei_v");
+       gl_get_floati_v = dlsym(RTLD_NEXT, "glGetFloati_v");
+       gl_get_integeri_v = dlsym(RTLD_NEXT, "glGetIntegeri_v");
+       gl_get_integer64i_v = dlsym(RTLD_NEXT, "glGetInteger64i_v");*/
+
+       if(init_valid_extensions() == -1) {
+               fprintf(stderr, "GLIAR: failed to initialize the valid extension list, might end up with unavailable extensions!\n");
+       }
+
        if(!(cfglist = gliar_load_cfg("gliar.conf"))) {
                struct passwd *pw;
                char *homedir, *path;
        if(!(cfglist = gliar_load_cfg("gliar.conf"))) {
                struct passwd *pw;
                char *homedir, *path;
@@ -72,22 +99,58 @@ static int init(void)
                }
        }
 
                }
        }
 
-       gl_get_string = dlsym(RTLD_NEXT, "glGetString");
-/*     gl_get_stringi = dlsym(RTLD_NEXT, "glGetStringi");
+       done_init = 1;
+       return 0;
+}
 
 
-       gl_get_booleanv = dlsym(RTLD_NEXT, "glGetBooleanv");
-       gl_get_doublev = dlsym(RTLD_NEXT, "glGetDoublev");
-       gl_get_floatv = dlsym(RTLD_NEXT, "glGetFloatv");
-       gl_get_integerv = dlsym(RTLD_NEXT, "glGetIntegerv");
-       gl_get_integer64v = dlsym(RTLD_NEXT, "glGetInteger64v");
+static int init_valid_extensions(void)
+{
+       int i, num_ext, prev_space = 0;
+       const char *gl_ext_str;
+       char *ext_str, *tok, *ptr, **ext_table;
 
 
-       gl_get_booleani_v = dlsym(RTLD_NEXT, "glGetBooleani_v");
-       gl_get_doublei_v = dlsym(RTLD_NEXT, "glGetDoublei_v");
-       gl_get_floati_v = dlsym(RTLD_NEXT, "glGetFloati_v");
-       gl_get_integeri_v = dlsym(RTLD_NEXT, "glGetIntegeri_v");
-       gl_get_integer64i_v = dlsym(RTLD_NEXT, "glGetInteger64i_v");*/
+       /* initialize the list of valid extensions */
+       if(!(gl_ext_str = (const char*)gl_get_string(GL_EXTENSIONS))) {
+               return -1;
+       }
 
 
-       done_init = 1;
+       if(!(ext_str = malloc(strlen(gl_ext_str) + 1))) {
+               return -1;
+       }
+       strcpy(ext_str, gl_ext_str);
+
+       /* count the extensions */
+       num_ext = 0;
+       ptr = ext_str;
+       while(*ptr) {
+               if(isspace(*ptr) && prev_space == 0) {
+                       prev_space = 1;
+                       num_ext++;
+               } else {
+                       prev_space = 0;
+               }
+               ptr++;
+       }
+
+       /* allocate extension table */
+       if(!(ext_table = malloc(num_ext * sizeof *ext_table))) {
+               free(ext_str);
+               return -1;
+       }
+
+       /* setup the ext_table slots to point to the start of each substring (extension) */
+       for(i=0; i<num_ext; i++) {
+               if(!(tok = strtok(i == 0 ? ext_str : 0, " \t\v\n\r"))) {
+                       fprintf(stderr, "DEBUG: strtok returned 0 at token %d\n", i);
+                       num_ext = i;
+               }
+               ext_table[i] = tok;
+       }
+
+       gliar_value_set("extensions", ext_table, num_ext);
+
+       free(ext_table);
+       free(ext_str);
        return 0;
 }
 
        return 0;
 }
 
@@ -129,3 +192,71 @@ const GLubyte *glGetString(GLenum name)
 
        return gl_get_string(name);
 }
 
        return gl_get_string(name);
 }
+
+const GLubyte *glGetStringi(GLenum name, GLuint index)
+{
+       char *key;
+       const struct cfgopt *option;
+
+       init();
+
+       switch(name) {
+       case GL_EXTENSIONS:
+               key = "extensions";
+               break;
+
+       case GL_SHADING_LANGUAGE_VERSION:
+               key = "sl version";
+               break;
+
+       default:
+               key = 0;
+       }
+
+       if(key && (option = gliar_find_opt(cfglist, key))) {
+               return (const GLubyte*)option->str_val[index];
+       }
+
+       return gl_get_stringi(name, index);
+}
+
+void glGetIntegerv(GLenum name, GLint *val)
+{
+       char *key;
+       const struct cfgopt *option;
+
+       init();
+
+       switch(name) {
+       case GL_NUM_EXTENSIONS:
+               if(1) {
+                       key = "extensions";
+               } else {
+       case GL_NUM_SHADING_LANGUAGE_VERSIONS:
+                       key = "sl version";
+               }
+               if(key && (option = gliar_find_opt(cfglist, key))) {
+                       *val = option->str_count;
+                       return;
+               }
+               break;
+
+       case GL_MAX_TEXTURE_UNITS:
+               key = "max texture units";
+               break;
+
+       case GL_MAX_TEXTURE_SIZE:
+               key = "max texture size";
+               break;
+
+       default:
+               key = 0;
+       }
+
+       if(key && (option = gliar_find_opt(cfglist, key)) && option->type == GLIAR_NUMBER) {
+               *val = option->num_val;
+               return;
+       }
+
+       gl_get_integerv(name, val);
+}