added delayed init call after scenegraph/meshes are done loading
[laserbrain_demo] / src / exman.cc
index 31ee1ae..00f7e39 100644 (file)
@@ -8,6 +8,7 @@
 #include "geomdraw.h"
 
 static Exhibit *create_exhibit(const char *type);
+static void clean_desc_text(char *dest, const char *src);
 
 
 ExhibitSlot::ExhibitSlot(Exhibit *ex)
@@ -152,6 +153,8 @@ bool ExhibitManager::remove(Exhibit *ex)
 
 bool ExhibitManager::load(MetaScene *mscn, const char *fname)
 {
+       info_log("ExhibitManager::load(%s)\n", fname);
+
        struct ts_node *root = ts_load(fname);
        if(!root || strcmp(root->name, "exhibits") != 0) {
                ts_free_tree(root);
@@ -242,9 +245,13 @@ bool ExhibitManager::load(MetaScene *mscn, const char *fname)
                        const char *voice = ts_get_attr_str(node, "voiceover");
                        if(desc || voice) {
                                ExData exd;
+                               exd.type = EXDATA_INFO;
 
                                if(desc) {
-                                       exd.text = std::string(desc);
+                                       char *fixed_desc = new char[strlen(desc) + 1];
+                                       clean_desc_text(fixed_desc, desc);
+                                       exd.text = std::string(fixed_desc);
+                                       delete [] fixed_desc;
                                }
                                if(voice) {
                                        exd.voice = new OggVorbisStream;
@@ -281,13 +288,14 @@ ExSelection ExhibitManager::select(const Ray &ray) const
 
 ExSelection ExhibitManager::select(const Sphere &sph) const
 {
-       ExSelection sel;
-       if(!items.empty()) {
-               sel.ex = items[0];
-               sel.selsphere = sph;
-               sel.validmask = EXSEL_SPHERE;
+       int nitems = items.size();
+       for(int i=0; i<nitems; i++) {
+               ExSelection sel = items[i]->select(sph);
+               if(sel) {
+                       return sel;
+               }
        }
-       return sel;     // TODO
+       return ExSelection();
 }
 
 // TODO optimize
@@ -368,3 +376,27 @@ static Exhibit *create_exhibit(const char *type)
        error_log("unknown exhibit type: %s\n", type);
        return 0;
 }
+
+/* clean up description text to be more easily layed out later.
+ * more specifically:
+ *  - remove redundant spaces
+ *  - remove all newlines except as paragraph separators
+ *  - remove all other whitespace chars
+ * destination buffer must be as large as the source buffer
+ */
+static void clean_desc_text(char *dest, const char *src)
+{
+       while(*src) {
+               if(isspace(*src)) {
+                       if(*src == '\n' && *(src + 1) == '\n') {
+                               *dest++ = '\n';
+                       } else {
+                               *dest++ = ' ';
+                       }
+                       while(*src && isspace(*src)) ++src;
+               } else {
+                       *dest++ = *src++;
+               }
+       }
+       *dest = 0;
+}