windows port
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Mon, 2 Jan 2017 14:22:50 +0000 (16:22 +0200)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Mon, 2 Jan 2017 14:22:50 +0000 (16:22 +0200)
laserbrain_demo.vcxproj
laserbrain_demo.vcxproj.filters
src/datamap.cc
src/optcfg.c [new file with mode: 0644]
src/optcfg.h [new file with mode: 0644]
src/shadow.cc

index 65d6e82..4812dd1 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>\r
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
   <ItemGroup Label="ProjectConfigurations">\r
     <ProjectConfiguration Include="Debug|Win32">\r
       <Configuration>Debug</Configuration>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
     <ConfigurationType>Application</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
-    <PlatformToolset>v120</PlatformToolset>\r
-    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v141</PlatformToolset>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
     <ConfigurationType>Application</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
-    <PlatformToolset>v120</PlatformToolset>\r
+    <PlatformToolset>v141</PlatformToolset>\r
     <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>Unicode</CharacterSet>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
   <ImportGroup Label="ExtensionSettings">\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <DisableSpecificWarnings>4244;4305;4996</DisableSpecificWarnings>\r
+      <PreprocessorDefinitions>WIN32;SDL_MAIN_HANDLED;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <DisableSpecificWarnings>4244;4305;4996;4800</DisableSpecificWarnings>\r
       <AdditionalIncludeDirectories>$(ProjectDir)\src;$(ProjectDir)\src\machine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <Link>\r
       <SubSystem>Console</SubSystem>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <AdditionalDependencies>opengl32.lib;freeglut.lib;glew32.lib;libgmath.lib;libvmath.lib;libimago2.lib;zlib.lib;libpng.lib;libjpeg.lib;libresman.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>opengl32.lib;glu32.lib;glew32.lib;SDL2.lib;libgmath.lib;libimago2.lib;zlib.lib;libpng.lib;libjpeg.lib;libresman.lib;treestore.lib;libgoatvr.lib;libdrawtext.lib;assimp.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
@@ -69,8 +69,8 @@
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <DisableSpecificWarnings>4244;4305;4996</DisableSpecificWarnings>\r
+      <PreprocessorDefinitions>WIN32;SDL_MAIN_HANDLED;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <DisableSpecificWarnings>4244;4305;4996;4800</DisableSpecificWarnings>\r
       <AdditionalIncludeDirectories>$(ProjectDir)\src;$(ProjectDir)\src\machine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <Link>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <OptimizeReferences>true</OptimizeReferences>\r
-      <AdditionalDependencies>opengl32.lib;freeglut.lib;glew32.lib;libgmath.lib;libvmath.lib;libimago2.lib;zlib.lib;libpng.lib;libjpeg.lib;libresman.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>opengl32.lib;glu32.lib;glew32.lib;SDL2.lib;libgmath.lib;libimago2.lib;zlib.lib;libpng.lib;libjpeg.lib;libresman.lib;treestore.lib;libgoatvr.lib;libdrawtext.lib;assimp.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <ClCompile Include="src\app.cc" />\r
+    <ClCompile Include="src\blobs\metasurf.c" />\r
+    <ClCompile Include="src\blob_exhibit.cc" />\r
     <ClCompile Include="src\datamap.cc" />\r
+    <ClCompile Include="src\exhibit.cc" />\r
     <ClCompile Include="src\geom.cc" />\r
     <ClCompile Include="src\image.cc" />\r
+    <ClCompile Include="src\logger.cc" />\r
     <ClCompile Include="src\machine\gear.cc" />\r
     <ClCompile Include="src\machine\machine.cc" />\r
     <ClCompile Include="src\machine\mparser.cc" />\r
     <ClCompile Include="src\material.cc" />\r
     <ClCompile Include="src\mesh.cc" />\r
     <ClCompile Include="src\meshgen.cc" />\r
+    <ClCompile Include="src\metascene.cc" />\r
     <ClCompile Include="src\object.cc" />\r
     <ClCompile Include="src\objmesh.cc" />\r
+    <ClCompile Include="src\opt.cc" />\r
+    <ClCompile Include="src\optcfg.c" />\r
+    <ClCompile Include="src\post.cc" />\r
     <ClCompile Include="src\scene.cc" />\r
     <ClCompile Include="src\sceneload.cc" />\r
     <ClCompile Include="src\sdr.c" />\r
+    <ClCompile Include="src\shader.cc" />\r
     <ClCompile Include="src\shadow.cc" />\r
     <ClCompile Include="src\snode.cc" />\r
     <ClCompile Include="src\texture.cc" />\r
+    <ClCompile Include="src\ui.cc" />\r
+    <ClCompile Include="src\unistate.cc" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="src\app.h" />\r
+    <ClInclude Include="src\blobs\mcubes.h" />\r
+    <ClInclude Include="src\blobs\metasurf.h" />\r
+    <ClInclude Include="src\blob_exhibit.h" />\r
     <ClInclude Include="src\datamap.h" />\r
     <ClInclude Include="src\dataset.h" />\r
     <ClInclude Include="src\exhibit.h" />\r
     <ClInclude Include="src\geom.h" />\r
     <ClInclude Include="src\image.h" />\r
+    <ClInclude Include="src\logger.h" />\r
     <ClInclude Include="src\machine\gear.h" />\r
     <ClInclude Include="src\machine\machine.h" />\r
     <ClInclude Include="src\machine\mparser.h" />\r
     <ClInclude Include="src\mech_exhibit.h" />\r
     <ClInclude Include="src\mesh.h" />\r
     <ClInclude Include="src\meshgen.h" />\r
+    <ClInclude Include="src\metascene.h" />\r
     <ClInclude Include="src\object.h" />\r
     <ClInclude Include="src\objmesh.h" />\r
     <ClInclude Include="src\opengl.h" />\r
+    <ClInclude Include="src\opt.h" />\r
+    <ClInclude Include="src\optcfg.h" />\r
+    <ClInclude Include="src\post.h" />\r
     <ClInclude Include="src\scene.h" />\r
     <ClInclude Include="src\sceneload.h" />\r
     <ClInclude Include="src\sdr.h" />\r
+    <ClInclude Include="src\shader.h" />\r
     <ClInclude Include="src\shadow.h" />\r
     <ClInclude Include="src\snode.h" />\r
     <ClInclude Include="src\texture.h" />\r
+    <ClInclude Include="src\ui.h" />\r
+    <ClInclude Include="src\unistate.h" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="sdr\shadow-notex.p.glsl" />\r
index 43d5a0d..b7d0998 100644 (file)
@@ -11,6 +11,9 @@
     <Filter Include="sdr">\r
       <UniqueIdentifier>{8e6a8961-784c-4356-9074-885fb1660b86}</UniqueIdentifier>\r
     </Filter>\r
+    <Filter Include="src\blobs">\r
+      <UniqueIdentifier>{7fd64b59-c051-40c0-8179-cbf5b6087114}</UniqueIdentifier>\r
+    </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="src\app.cc">\r
     <ClCompile Include="src\machine\mparser.cc">\r
       <Filter>src\machine</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="src\blob_exhibit.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\exhibit.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\logger.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\metascene.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\opt.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\post.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\shader.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\ui.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\unistate.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\blobs\metasurf.c">\r
+      <Filter>src\blobs</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\optcfg.c">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="src\app.h">\r
     <ClInclude Include="src\machine\mparser.h">\r
       <Filter>src\machine</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="src\blob_exhibit.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\logger.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\metascene.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\opt.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\post.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\shader.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\ui.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\unistate.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\blobs\mcubes.h">\r
+      <Filter>src\blobs</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\blobs\metasurf.h">\r
+      <Filter>src\blobs</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\optcfg.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="src\dataset.inl">\r
index e448923..d39de6a 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <algorithm>
 #include "datamap.h"
 
 #ifdef WIN32
diff --git a/src/optcfg.c b/src/optcfg.c
new file mode 100644 (file)
index 0000000..ab84474
--- /dev/null
@@ -0,0 +1,354 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+#include "optcfg.h"
+
+struct optcfg {
+       struct optcfg_option *optlist;
+
+       optcfg_opt_callback opt_func;
+       void *opt_cls;
+       optcfg_arg_callback arg_func;
+       void *arg_cls;
+
+       int err_abort;
+
+       /* argument parsing state */
+       char **argv;
+       int argidx;
+       int disable_opt;
+
+       /* config file parsing state */
+       const char *cfg_fname;
+       int cfg_nline;
+       char *cfg_value;
+};
+
+static int get_opt(struct optcfg *oc, const char *s, int *disable_opt);
+static char *skip_spaces(char *s);
+static void strip_comments(char *s);
+static void strip_trailing_spaces(char *s);
+static char *parse_keyval(char *line);
+
+
+struct optcfg *optcfg_init(struct optcfg_option *optv)
+{
+       struct optcfg *oc;
+
+       if(!(oc = calloc(1, sizeof *oc))) {
+               return 0;
+       }
+       oc->optlist = optv;
+       oc->err_abort = 1;
+       return oc;
+}
+
+void optcfg_destroy(struct optcfg *oc)
+{
+       memset(oc, 0, sizeof *oc);
+       free(oc);
+}
+
+void optcfg_set_opt_callback(struct optcfg *oc, optcfg_opt_callback func, void *cls)
+{
+       oc->opt_func = func;
+       oc->opt_cls = cls;
+}
+
+void optcfg_set_arg_callback(struct optcfg *oc, optcfg_arg_callback func, void *cls)
+{
+       oc->arg_func = func;
+       oc->arg_cls = cls;
+}
+
+void optcfg_set_error_action(struct optcfg *oc, int act)
+{
+       if(act == OPTCFG_ERROR_FAIL) {
+               oc->err_abort = 1;
+       } else if(act == OPTCFG_ERROR_IGNORE) {
+               oc->err_abort = 0;
+       }
+}
+
+int optcfg_parse_args(struct optcfg *oc, int argc, char **argv)
+{
+       int i;
+
+       oc->argv = argv;
+
+       for(i=1; i<argc; i++) {
+               oc->argidx = i;
+
+               if(argv[i][0] == '-') {
+                       if(oc->opt_func) {
+                               int o = get_opt(oc, argv[i], &oc->disable_opt);
+                               if(o == -1 || oc->opt_func(oc, o, oc->opt_cls) == -1) {
+                                       if(oc->err_abort) {
+                                               fprintf(stderr, "unexpected option: %s\n", argv[i]);
+                                               return -1;
+                                       }
+                               }
+                       } else {
+                               fprintf(stderr, "unexpected option: %s\n", argv[i]);
+                               if(oc->err_abort) {
+                                       return -1;
+                               }
+                       }
+               } else {
+                       if(oc->arg_func) {
+                               if(oc->arg_func(oc, argv[i], oc->arg_cls) == -1) {
+                                       if(oc->err_abort) {
+                                               fprintf(stderr, "unexpected argument: %s\n", argv[i]);
+                                               return -1;
+                                       }
+                               }
+                       } else {
+                               fprintf(stderr, "unexpected argument: %s\n", argv[i]);
+                               if(oc->err_abort) {
+                                       return -1;
+                               }
+                       }
+               }
+
+               i = oc->argidx;
+       }
+
+       oc->argidx = 0; /* done parsing args */
+       return 0;
+}
+
+int optcfg_parse_config_file(struct optcfg *oc, const char *fname)
+{
+       int res;
+       FILE *fp = fopen(fname, "rb");
+       if(!fp) {
+               return -1;
+       }
+
+       oc->cfg_fname = fname;
+       res = optcfg_parse_config_stream(oc, fp);
+       oc->cfg_fname = 0;
+       fclose(fp);
+       return res;
+}
+
+int optcfg_parse_config_stream(struct optcfg *oc, FILE *fp)
+{
+       char buf[512];
+
+       oc->cfg_nline = 0;
+       while(fgets(buf, sizeof buf, fp)) {
+               ++oc->cfg_nline;
+
+               if(optcfg_parse_config_line(oc, buf) == -1) {
+                       if(oc->err_abort) {
+                               return -1;
+                       }
+               }
+       }
+       return 0;
+}
+
+int optcfg_parse_config_line(struct optcfg *oc, const char *line)
+{
+       int opt, len;
+       char *start, *val, *buf;
+
+       len = strlen(line);
+       buf = alloca(len + 1);
+       memcpy(buf, line, len + 1);
+
+       start = skip_spaces(buf);
+       strip_comments(start);
+       strip_trailing_spaces(start);
+       if(!*start) {
+               return 0;
+       }
+
+       if(!(val = parse_keyval(start))) {
+               fprintf(stderr, "error parsing %s line %d: invalid syntax\n", oc->cfg_fname ? oc->cfg_fname : "", oc->cfg_nline);
+               return -1;
+       }
+       oc->cfg_value = val;
+       if((opt = get_opt(oc, start, 0)) == -1) {
+               fprintf(stderr, "error parsing %s line %d: unknown option: %s\n", oc->cfg_fname ? oc->cfg_fname : "",
+                               oc->cfg_nline, start);
+               return -1;
+       }
+
+       if(oc->opt_func) {
+               if(oc->opt_func(oc, opt, oc->opt_cls) == -1) {
+                       return -1;
+               }
+       }
+       oc->cfg_value = 0;
+       return 0;
+}
+
+int optcfg_enabled_value(struct optcfg *oc, int *enabledp)
+{
+       if(oc->argidx) {
+               *enabledp = ~oc->disable_opt & 1;
+       } else {
+               char *val = optcfg_next_value(oc);
+               if(optcfg_bool_value(val, enabledp) == -1) {
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+
+char *optcfg_next_value(struct optcfg *oc)
+{
+       if(oc->argidx) {        /* we're in the middle of parsing arguments, so get the next one */
+               return oc->argv[++oc->argidx];
+       }
+       if(oc->cfg_value) {
+               char *val = oc->cfg_value;
+               oc->cfg_value = 0;
+               return val;
+       }
+       return 0;
+}
+
+void optcfg_print_options(struct optcfg *oc)
+{
+       int i;
+       for(i=0; oc->optlist[i].opt != -1; i++) {
+               struct optcfg_option *opt = oc->optlist + i;
+
+               if(opt->c) {
+                       printf(" -%c", opt->c);
+               } else {
+                       printf("   ");
+               }
+               if(opt->s) {
+                       printf("%c-%s: ", opt->c ? ',' : ' ', opt->s);
+               } else {
+                       printf(": ");
+               }
+               printf("%s\n", opt->desc ? opt->desc : "undocumented");
+       }
+}
+
+#ifdef _MSC_VER
+#define strcasecmp stricmp
+#endif
+
+int optcfg_bool_value(char *s, int *valret)
+{
+       if(strcasecmp(s, "yes") == 0 || strcasecmp(s, "true") == 0 || strcmp(s, "1") == 0) {
+               *valret = 1;
+               return 0;
+       }
+       if(strcasecmp(s, "no") == 0 || strcasecmp(s, "false") == 0 || strcmp(s, "0") == 0) {
+               *valret = 0;
+               return 0;
+       }
+       return -1;
+}
+
+int optcfg_int_value(char *str, int *valret)
+{
+       char *endp;
+       *valret = strtol(str, &endp, 0);
+       if(endp == str) {
+               return -1;
+       }
+       return 0;
+}
+
+int optcfg_float_value(char *str, float *valret)
+{
+       char *endp;
+       *valret = strtod(str, &endp);
+       if(endp == str) {
+               return -1;
+       }
+       return 0;
+}
+
+
+
+static int get_opt(struct optcfg *oc, const char *arg, int *disable_opt)
+{
+       int i, ndashes = 0;
+
+       while(*arg && *arg == '-') {
+               ++ndashes;
+               ++arg;
+       }
+
+       if(ndashes > 2) {
+               arg -= ndashes;
+               ndashes = 0;
+       }
+
+       if(disable_opt) {
+               if(ndashes && (strstr(arg, "no-") == arg || strstr(arg, "disable-") == arg)) {
+                       *disable_opt = 1;
+                       arg = strchr(arg, '-') + 1;     /* guaranteed to exist at this point */
+               } else {
+                       *disable_opt = 0;
+               }
+       }
+
+       if(arg[1]) {    /* match long options */
+               for(i=0; oc->optlist[i].opt != -1; i++) {
+                       if(strcmp(arg, oc->optlist[i].s) == 0) {
+                               return i;
+                       }
+               }
+       } else {
+               for(i=0; oc->optlist[i].opt != -1; i++) {
+                       if(arg[0] == oc->optlist[i].c) {
+                               return i;
+                       }
+               }
+       }
+       return -1;
+}
+
+static char *skip_spaces(char *s)
+{
+       while(*s && isspace(*s)) ++s;
+       return s;
+}
+
+static void strip_comments(char *s)
+{
+       while(*s && *s != '#') ++s;
+       if(*s == '#') *s = 0;
+}
+
+static void strip_trailing_spaces(char *s)
+{
+       char *end = s + strlen(s) - 1;
+       while(end >= s && isspace(*end)) {
+               *end-- = 0;
+       }
+}
+
+static char *parse_keyval(char *line)
+{
+       char *val;
+       char *eq = strchr(line, '=');
+       if(!eq) return 0;
+
+       *eq = 0;
+       strip_trailing_spaces(line);
+       val = skip_spaces(eq + 1);
+       strip_trailing_spaces(val);
+
+       if(!*line || !*val) {
+               return 0;
+       }
+       return val;
+}
diff --git a/src/optcfg.h b/src/optcfg.h
new file mode 100644 (file)
index 0000000..b6d060a
--- /dev/null
@@ -0,0 +1,90 @@
+/* generic unified commandline option and config file parsing library */
+#ifndef LIBOPTCFG_H_
+#define LIBOPTCFG_H_
+
+#include <stdio.h>
+
+struct optcfg;
+
+struct optcfg_option {
+       char c;                         /* short (optional): used only for argument parsing */
+       const char *s;          /* long: used for long options and config files */
+       int opt;                        /* the corresponding option enumeration */
+       const char *desc;       /* text description for printing usage information */
+};
+
+#define OPTCFG_OPTIONS_END     {0, 0, -1, 0}
+
+typedef int (*optcfg_opt_callback)(struct optcfg *oc, int opt, void *cls);
+typedef int (*optcfg_arg_callback)(struct optcfg *oc, const char *arg, void *cls);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* initialize the optcfg object with a valid option vector terminated by an
+ * entry with an opt value of -1 (other fields ignored for termination purposes)
+ *
+ * Example:
+ *   struct optcfg_option options[] = {
+ *       {'f', "foo", OPT_FOO, "Makes sure the foo is bar"},
+ *       {'h', "help", OPT_HELP, "Print usage information and exit"},
+ *       OPTCFG_OPTIONS_END
+ *   };
+ *   struct optcfg *oc = optcfg_init(options);
+ */
+struct optcfg *optcfg_init(struct optcfg_option *optv);
+void optcfg_destroy(struct optcfg *oc);
+
+/* The parse_* functions call the option callback for each option.
+ *
+ * The option callback can then call optcfg_next_value to retrieve any
+ * values attached to this option. When optcfg_next_value returns 0, there
+ * are no more values available.
+ * The option callback must return 0 for success, and -1 to abort parsing.
+ */
+void optcfg_set_opt_callback(struct optcfg *oc, optcfg_opt_callback func, void *cls);
+/* the argument callback is only called from optcfg_parse_args(), when a non-option
+ * argument is encountered (an argument not starting with a dash)
+ */
+void optcfg_set_arg_callback(struct optcfg *oc, optcfg_arg_callback func, void *cls);
+
+enum { OPTCFG_ERROR_FAIL, OPTCFG_ERROR_IGNORE };
+void optcfg_set_error_action(struct optcfg *oc, int act);
+
+int optcfg_parse_args(struct optcfg *oc, int argc, char **argv);
+int optcfg_parse_config_file(struct optcfg *oc, const char *fname);
+int optcfg_parse_config_stream(struct optcfg *oc, FILE *fp);
+int optcfg_parse_config_line(struct optcfg *oc, const char *line);
+/* TODO custom I/O callback version of config file parsing */
+
+/* special value function which returns if the option is enabled or disabled
+ * For config files it works similar to calling optcfg_next_value, and
+ * optcfg_bool_value in sequence.
+ * For argument parsing however, it doesn't consume further arguments. Merely
+ * the presence of the option makes it enabled, and its presence with a -no-
+ * or -disable- prefix disables it.
+ */
+int optcfg_enabled_value(struct optcfg *oc, int *enabledp);
+
+/* call optcfg_next_value in the option callback to retrieve the next value
+ * of the current option. returns 0 if there is no next value.
+ */
+char *optcfg_next_value(struct optcfg *oc);
+
+/* helper function which can be used to print the available options */
+void optcfg_print_options(struct optcfg *oc);
+
+/* helper functions to convert value strings to typed values
+ * returns 0 for success and value is returned through the valret pointer,
+ * otherwise it returns -1 for type mismatch, and valret contents are undefined
+ */
+int optcfg_bool_value(char *str, int *valret); /* accepts yes/no, true/false, 1/0 */
+int optcfg_int_value(char *str, int *valret);
+int optcfg_float_value(char *str, float *valret);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBOPTCFG_H_ */
index 357ed82..0f21abe 100644 (file)
@@ -2,7 +2,14 @@
 #include <assert.h>
 #include "opengl.h"
 #include "shadow.h"
+
+#undef DBG_USE_VMATH
+
+#ifdef DBG_USE_VMATH
 #include "vmath/vmath.h"
+#else
+#include "gmath/gmath.h"
+#endif
 
 
 bool shadow_pass;
@@ -67,6 +74,7 @@ void begin_shadow_pass(const gph::Vec3 &lpos, const gph::Vec3 &ltarg, float lfov
        glColorMask(0, 0, 0, 0);
        glDepthMask(1);
 
+#ifdef DBG_USE_VMATH
        Matrix4x4 viewmat;
        glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]);
        viewmat.transpose();
@@ -86,13 +94,12 @@ void begin_shadow_pass(const gph::Vec3 &lpos, const gph::Vec3 &ltarg, float lfov
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadTransposeMatrixf(lt_viewmat[0]);
-
-
-       /*gph::Mat4 viewmat;
+#else
+       gph::Mat4 viewmat;
        glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]);
 
        gph::Mat4 lt_viewmat, lt_projmat;
-       lt_projmat.perspective(deg_to_rad(lfov) * 2.0, 1.0, znear, zfar);
+       lt_projmat.perspective(gph::deg_to_rad(lfov) * 2.0, 1.0, znear, zfar);
        lt_viewmat.inv_lookat(lpos, ltarg, gph::Vec3(0, 1, 0));
        shadow_mat = lt_projmat * lt_viewmat * viewmat.inverse();
        //shadow_mat = viewmat.inverse() * lt_viewmat * lt_projmat;
@@ -105,7 +112,7 @@ void begin_shadow_pass(const gph::Vec3 &lpos, const gph::Vec3 &ltarg, float lfov
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadMatrixf(lt_viewmat[0]);
-       */
+#endif
 
        glGetIntegerv(GL_VIEWPORT, prev_vp);
        glViewport(0, 0, tex_sz, tex_sz);