beginnings of scene rendering
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Wed, 29 Jul 2009 05:51:42 +0000 (23:51 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Wed, 29 Jul 2009 05:51:42 +0000 (23:51 -0600)
configure.ac
doc/yoink.6.in
src/Makefile.am
src/YoinkApp.cc
src/YoinkApp.hh
src/opengl.hh
src/scene.cc
src/tilemap.cc
src/tilemap.hh

index 63f2034434e53fce1b191899511b865e1a25da68..cc0e8be8c8f81a22ef3de62313f2ff6c6b20da78 100644 (file)
@@ -101,6 +101,9 @@ AC_SEARCH_LIBS([IMG_Load], [SDL_image],,
 AC_SEARCH_LIBS([glBegin], [GL],,
                           [AC_MSG_ERROR([libGL is required])])
 
+AC_SEARCH_LIBS([gluPerspective], [GLU],,
+                          [AC_MSG_ERROR([libGLU is required])])
+
 AC_SEARCH_LIBS([clock_gettime], [rt],
                           [AC_DEFINE([HAVE_CLOCK_GETTIME], 1,
                                                  [Define to 1 if you have the 'clock_gettime' function.])])
index 5425c3a91f23021168972ed7120e6e1b591fcfa3..c5eec633ed774b9fce72558e549db4137670ff1b 100644 (file)
@@ -85,11 +85,12 @@ looks for configuration files and loads them in this order, with the options in
 prior configuration files taking precedence over the same options if they exist
 in multiple configuration files:
 .TP
-1. $YOINK_CONFIGFILE
-This is an optional environment variable.
+1. $YOINKRC
+This is an optional environment variable you can set to point to a configuration
+file.
 .TP
 2. $HOME/.yoinkrc
-This is a specific user's configuration file.
+This is a specific user's personal configuration file.
 .TP
 3. /etc/yoinkrc
 This is the system-wide configuration file.
@@ -213,29 +214,33 @@ responds to some variables in the environment:
 HOME
 If set to a path of a valid directory (presumably a user's home directory),
 .B yoink
-will load options from the configuration file at $HOME/.yoinkrc, if it exists.
-Saving options within the game will cause this file to be over-written with the
-new options.
+will look for a file at
+.I $HOME/.yoinkrc
+and load it as a configuration file.  Saving options within the game will cause
+this file to be over-written with the new options, unless the
+.I YOINKRC
+variable is set.
 .TP
 USER
 .B yoink
 uses this variable to guess the user's nickname, for a high score entry or
 whatever.
 .TP
-YOINK_CONFIGFILE
-If set to a path of a valid configuration file, 
-.B yoink
-will load the options from that file, and those options will take precedence
-over options loaded from other configuration files.  Any in-game saving will
-cause this file to be over-written by the new options rather than the file at
-$HOME/.yoinkrc.
-.TP
 YOINK_DATADIR
 If set to a path of a valid directory, 
 .B yoink
 will look in this directory first when it is loading game assets.  Set this
-variable if you move the game's assets to another directory or want to load your
-own assets.
+variable if you move the game's assets to another directory or perhaps want to
+load your own custom assets rather than the defaults.
+.TP
+YOINKRC
+If set to a path of a valid configuration file, 
+.B yoink
+will load the options from that file, and those options will take precedence
+over options loaded from other configuration files.  Any in-game saving will
+cause this file to be over-written by the new options rather than the
+.I $HOME/.yoinkrc
+config file.
 .br
 .SH NOTES
 .PP
index ca4f81ef3f86e19d104a7bb0f2ec5574ca1ccb0a..0c9b062b892dff0e614e8e0a69ead4133e625120 100644 (file)
@@ -48,7 +48,7 @@ libdc_la_SOURCES = \
                                   video.hh \
                                   $(ENDLIST)
 
-libdc_la_CPPFLAGS = -I/usr/include/SDL -I$(top_srcdir)/yajl/src
+libdc_la_CPPFLAGS = -I$(top_srcdir)/yajl/src
 libdc_la_LIBADD   = $(top_srcdir)/yajl/libyajl.la
 
 
@@ -65,7 +65,6 @@ yoink_SOURCES  = \
                                 YoinkApp.hh \
                                 $(ENDLIST)
 
-yoink_CPPFLAGS = -I/usr/include/SDL
 yoink_LDADD    = libdc.la
 
 
@@ -73,7 +72,7 @@ EXTRA_DIST = cml
 
 
 YOINK_ENVIRONMENT = YOINK_DATADIR="$(top_srcdir)/data" \
-                                       YOINK_CONFIGFILE="$(top_srcdir)/data/yoinkrc"
+                                       YOINKRC="$(top_srcdir)/data/yoinkrc"
 
 run: all
        $(YOINK_ENVIRONMENT) ./yoink
index f0a1ad988864fa2388dac6cac0a56c7ebf9c9035..655aa3497928e5c22b6510f8725efa95d86a5368 100644 (file)
 
 #include <boost/bind.hpp>
 
+#include "math.hh"
 #include "opengl.hh"
-#include "video.hh"
 #include "settings.hh"
-
-#include "math.hh"
+#include "timer.hh"
+#include "video.hh"
 
 #include "YoinkApp.hh"
 
-#include "timer.hh"
-
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -52,12 +50,12 @@ static std::string configFiles()
 {
        std::string files;
 
-       char* configFile = getenv("YOINK_CONFIGFILE");
+       char* configFile = getenv("YOINKRC");
 
        if (configFile)
        {
                // if a config file from the environment variable is specified, we want
-               // to load it first
+               // to load it first so it has precedence
                files += configFile;
                files += ":";
        }
@@ -135,7 +133,7 @@ void YoinkApp::setupGL()
 
        glClearColor(0.0, 0.0, 1.0, 1.0);
 
-       glLineWidth(10.0f);
+       //glLineWidth(10.0f);
 }
 
 void YoinkApp::contextRecreated(const dc::notification& note)
@@ -162,21 +160,33 @@ void YoinkApp::update(dc::scalar t, dc::scalar dt)
 
 void YoinkApp::draw(dc::scalar alpha)
 {
-       dc::vector4 meh;
-       meh.random(0.0, 1.0);
-       static dc::vector4 c1(meh);
+       //dc::vector4 meh;
+       //meh.random(0.0, 1.0);
+       //static dc::vector4 c1(meh);
 
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-       dc::scalar drawstate = cml::lerp(prevstate, state, alpha);
-       dc::scalar sinstate = std::sin(drawstate);
-       dc::scalar cosstate = std::cos(drawstate);
+       //dc::scalar drawstate = cml::lerp(prevstate, state, alpha);
+       //dc::scalar sinstate = std::sin(drawstate);
+       //dc::scalar cosstate = std::cos(drawstate);
+       
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       gluPerspective(60.0, 1.33333, 1.0, 2000.0);
+       
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
 
+       glBindTexture(GL_TEXTURE_2D, 0);
+       //glRotatef(drawstate*15.0f, 0.0, 1.0, 0.0);
+       glTranslatef(x, y, z);
 
        // DRAW THE SCENE
        testScene->draw(alpha);
 
 
+       /*
        someChar->getTilemap().bind();
        glColor3f(1.0, 1.0, 1.0);
 
@@ -289,7 +299,7 @@ void YoinkApp::draw(dc::scalar alpha)
        glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
 
        glDisable(GL_BLEND);
-       glEnable(GL_DEPTH_TEST);
+       glEnable(GL_DEPTH_TEST);*/
 }
 
 void YoinkApp::handleEvent(const dc::event& e)
@@ -309,6 +319,30 @@ void YoinkApp::handleEvent(const dc::event& e)
                        {
                                someChar->getAnimation().startSequence("Punch");
                        }
+                       else if (e.key.keysym.sym == SDLK_RIGHT)
+                       {
+                               x -= 50.0;
+                       }
+                       else if (e.key.keysym.sym == SDLK_LEFT)
+                       {
+                               x += 50.0;
+                       }
+                       else if (e.key.keysym.sym == SDLK_UP)
+                       {
+                               y -= 50.0;
+                       }
+                       else if (e.key.keysym.sym == SDLK_DOWN)
+                       {
+                               y += 50.0;
+                       }
+                       else if (e.key.keysym.sym == SDLK_PAGEUP)
+                       {
+                               z += 50.0;
+                       }
+                       else if (e.key.keysym.sym == SDLK_PAGEDOWN)
+                       {
+                               z -= 50.0;
+                       }
                        break;
 
                case SDL_QUIT:
index 055a64c25ea97415d6a2f47bb844ae3188b46164..475dca35cd6d6259bacad22e4d8eb798976e5df9 100644 (file)
@@ -77,6 +77,8 @@ private:
 
        TilemapFont *font;
 
+       dc::scalar x, y, z;
+
        dc::scalar state;
        dc::scalar prevstate;
 };
index 287918dfdf8be3ba2600819bffb8e934584528e6..aa95164abe1a68467009df39b8d39486354799b7 100644 (file)
@@ -26,8 +26,8 @@
 
 *******************************************************************************/
 
-#ifndef _GL_HH_
-#define _GL_HH_
+#ifndef _OPENGL_HH_
+#define _OPENGL_HH_
 
 #ifdef __APPLE__
 #include <OpenGL/gl.h>
@@ -39,7 +39,7 @@
 #include <GL/glext.h>
 #endif
 
-#endif // _GL_HH_
+#endif // _OPENGL_HH_
 
 /** vim: set ts=4 sw=4 tw=80: *************************************************/
 
index 7dd102b0af30c146d99e5b2d7af1bcb316517bee..04754ea1730e22fb24b53e19bcba976122124155 100644 (file)
 
 *******************************************************************************/
 
+#include <iostream>
 #include <map>
 #include <vector>
 
-#include "mippleton.hh"
+#include "aabb.hh"
+#include "camera.hh"
+#include "cullable.hh"
 #include "deserializer.hh"
+#include "drawable.hh"
+#include "math.hh"
+#include "mippleton.hh"
+#include "opengl.hh"
 #include "serializable.hh"
-#include "aabb.hh"
+#include "tilemap.hh"
 
 #include "scene.hh"
 
@@ -42,6 +49,186 @@ namespace dc {
 
 class scene::scene_impl : public mippleton<scene_impl>
 {
+       class scenery : public drawable, public cullable
+       {
+       public:
+               scenery(const matrix4& transform, const std::string& textureName) :
+                       transformation(transform),
+                       image(textureName) {}
+
+       protected:
+               matrix4         transformation;
+               tilemap         image;
+               bool            blending;
+               long            detail;
+               bool            fog;
+       };
+
+       class tiles : public scenery
+       {
+       public:
+               tiles(const matrix4& transform, const std::string& textureName,
+                               serializable_ptr root) :
+                       scenery(transform, textureName),
+                       width(1),
+                       height(1)
+               {
+                       std::map<std::string,serializable_ptr> rootObj;
+
+                       if (root->get(rootObj))
+                       {
+                               std::map<std::string,serializable_ptr>::iterator it;
+
+                               if ((it = rootObj.find("width")) != rootObj.end())
+                               {
+                                       (*it).second->get(width);
+                               }
+                               if ((it = rootObj.find("tiles")) != rootObj.end())
+                               {
+                                       std::vector<serializable_ptr> theTiles;
+
+                                       if ((*it).second->get(theTiles))
+                                       {
+                                               std::vector<serializable_ptr>::iterator jt;
+
+                                               height = theTiles.size() / width;
+                                               int w, h;
+
+                                               indices.resize(height);
+
+                                               for (h = height - 1, jt = theTiles.begin();
+                                                               jt != theTiles.end(); h--)
+                                               {
+                                                       std::vector<unsigned> row;
+
+                                                       for (w = 0; w < width && jt != theTiles.end();
+                                                                       w++, jt++)
+                                                       {
+                                                               long index;
+
+                                                               if ((*jt)->get(index))
+                                                               {
+                                                                       row.push_back(unsigned(index));
+                                                               }
+                                                       }
+
+                                                       indices[h] = row;
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               void draw(scalar alpha)
+               {
+                       glPushMatrix();
+                       //std::cout << "transforming..." << std::endl;
+                       //std::cout << transformation << std::endl;
+                       glMultMatrixf(transformation.data());
+
+                       glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+                       image.bind();
+
+                       long x, y;
+                       scalar xf, yf;
+
+                       for (y = 0, yf = 0.0; y < height; y++, yf += 1.0)
+                       {
+                               for (x = 0, xf = 0.0; x < width; x++, xf += 1.0)
+                               {
+                                       scalar texCoords[8];
+
+                                       unsigned index = indices[y][x];
+
+                                       if (image.getTileCoords(index, texCoords))
+                                       {
+                                               glBegin(GL_TRIANGLE_FAN);
+                                                       glTexCoord2f(texCoords[0], texCoords[1]);
+                                                       glVertex3f(xf, yf, 0.0f);
+                                                       glTexCoord2f(texCoords[2], texCoords[3]);
+                                                       glVertex3f(xf+1.0, yf, 0.0f);
+                                                       glTexCoord2f(texCoords[4], texCoords[5]);
+                                                       glVertex3f(xf+1.0, yf+1.0, 0.0f);
+                                                       glTexCoord2f(texCoords[6], texCoords[7]);
+                                                       glVertex3f(xf, yf+1.0, 0.0f);
+                                               glEnd();
+                                       }
+                               }
+                       }
+
+                       glPopMatrix();
+               }
+
+               bool isVisible(const camera& cam)
+               {
+                       return true;
+               }
+
+       private:
+               long width, height;
+               std::vector<std::vector<unsigned> > indices;
+       };
+
+       class billboard : public scenery
+       {
+       public:
+               billboard(const matrix4& transform, const std::string& textureName,
+                               serializable_ptr root) :
+                       scenery(transform, textureName),
+                       index(0)
+               {
+                       std::map<std::string,serializable_ptr> rootObj;
+
+                       if (root->get(rootObj))
+                       {
+                               std::map<std::string,serializable_ptr>::iterator it;
+
+                               if ((it = rootObj.find("tile")) != rootObj.end())
+                               {
+                                       long value;
+                                       if ((*it).second->get(value))
+                                       {
+                                               index = unsigned(value);
+                                       }
+                               }
+                       }
+
+                       image.getTileCoords(index, texCoords);
+               }
+
+               void draw(scalar alpha)
+               {
+                       glPushMatrix();
+                       glMultMatrixf(transformation.data());
+
+                       glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+                       image.bind();
+
+                       glBegin(GL_TRIANGLE_FAN);
+                               glTexCoord2f(texCoords[0], texCoords[1]);
+                               glVertex2f(0.0f, 0.0f);
+                               glTexCoord2f(texCoords[2], texCoords[3]);
+                               glVertex2f(1.0f, 0.0f);
+                               glTexCoord2f(texCoords[4], texCoords[5]);
+                               glVertex2f(1.0f, 1.0f);
+                               glTexCoord2f(texCoords[6], texCoords[7]);
+                               glVertex2f(0.0f, 1.0f);
+                       glEnd();
+
+                       glPopMatrix();
+               }
+
+               bool isVisible(const camera& cam)
+               {
+                       return false;
+               }
+
+       private:
+               unsigned index;
+               scalar texCoords[8];
+       };
+
+
        static bool loadBox(aabb& theBox, serializable_ptr obj)
        {
                std::vector<serializable_ptr> numbers;
@@ -63,7 +250,6 @@ class scene::scene_impl : public mippleton<scene_impl>
        }
 
 public:
-
        scene_impl(const std::string& name) :
                mippleton<scene_impl>(name)
        {
@@ -71,6 +257,164 @@ public:
        }
 
 
+       void loadInstructions(serializable_ptr root)
+       {
+               std::vector<serializable_ptr> rootObj;
+
+               if (root->get(rootObj))
+               {
+                       std::vector<serializable_ptr>::iterator it;
+
+                       matrix4 transform;
+                       std::string texture;
+
+                       for (it = rootObj.begin(); it != rootObj.end(); it++)
+                       {
+                               std::string instruction;
+
+                               if ((*it)->get(instruction))
+                               {
+                                       if (instruction == "reset_transform")
+                                       {
+                                               transform.identity();
+                                               //std::cout << "===================RESET=====================" << std::endl;
+                                       }
+                                       else if (instruction == "translate")
+                                       {
+                                               std::vector<serializable_ptr> values;
+
+                                               it++;
+                                               if ((*it)->get(values))
+                                               {
+                                                       vector3 vec;
+
+                                                       for (unsigned i = 0; i < values.size(); i++)
+                                                       {
+                                                               double value;
+
+                                                               if (values[i]->getNumber(value))
+                                                               {
+                                                                       vec[i] = value;
+                                                               }
+                                                       }
+
+                                                       matrix4 translation;
+                                                       cml::matrix_translation(translation, vec);
+                                                       transform = translation * transform;
+                                                       //std::cout << "TRANSLATE\t" << vec << std::endl
+                                                               //<< transform << std::endl;
+                                               }
+                                       }
+                                       else if (instruction == "scale")
+                                       {
+                                               std::vector<serializable_ptr> values;
+
+                                               it++;
+                                               if ((*it)->get(values))
+                                               {
+                                                       if (values.size() == 1)
+                                                       {
+                                                               double value = 1.0;
+
+                                                               values[0]->getNumber(value);
+
+                                                               matrix4 scaling;
+                                                               cml::matrix_uniform_scale(scaling, scalar(value));
+                                                               transform = scaling * transform;
+                                                               //std::cout << "SCALE\t\t" << value << std::endl
+                                                                       //<< transform << std::endl;
+                                                       }
+                                                       else if (values.size() == 3)
+                                                       {
+                                                               vector3 vec;
+
+                                                               for (unsigned i = 0; i < values.size(); i++)
+                                                               {
+                                                                       double value;
+
+                                                                       if (values[i]->getNumber(value))
+                                                                       {
+                                                                               vec[i] = value;
+                                                                       }
+                                                               }
+
+                                                               matrix4 scaling;
+                                                               cml::matrix_scale(scaling, vec);
+                                                               transform = scaling * transform;
+                                                               //std::cout << "SCALE\t\t" << vec << std::endl
+                                                                       //<< transform << std::endl;
+                                                       }
+                                               }
+                                       }
+                                       else if (instruction == "rotate")
+                                       {
+                                               std::vector<serializable_ptr> values;
+
+                                               it++;
+                                               if ((*it)->get(values))
+                                               {
+                                                       if (values.size() == 2)
+                                                       {
+                                                               std::string axis;
+                                                               size_t axisIndex = 0;
+                                                               double value = 0.0;
+
+                                                               if (values[0]->get(axis))
+                                                               {
+                                                                       if (axis == "x")
+                                                                       {
+                                                                               axisIndex = 0;
+                                                                       }
+                                                                       else if (axis == "y")
+                                                                       {
+                                                                               axisIndex = 1;
+                                                                       }
+                                                                       else if (axis == "z")
+                                                                       {
+                                                                               axisIndex = 2;
+                                                                       }
+                                                                       values[1]->getNumber(value);
+                                                               }
+
+                                                               cml::matrix_rotate_about_local_axis(transform,
+                                                                               axisIndex, scalar(value * cml::constantsd::rad_per_deg()));
+                                                               //std::cout << "ROTATE\t" << axis << " " << value << std::endl
+                                                                       //<< transform << std::endl;
+                                                       }
+                                               }
+                                       }
+                                       else if (instruction == "texture")
+                                       {
+                                               it++;
+                                               (*it)->get(texture);
+                                       }
+                                       else if (instruction == "tilemap")
+                                       {
+                                               //std::cout << "TILEMAP\t" << texture<< std::endl;
+                                               //std::cout << transform << std::endl;
+
+                                               it++;
+                                               tiles* newTiles = new tiles(transform, texture, *it);
+                                               boost::shared_ptr<scenery> sceneItem(newTiles);
+                                               objects.push_back(sceneItem);
+                                       }
+                                       else if (instruction == "billboard")
+                                       {
+                                               //std::cout << "BILLBOARD\t" << texture << std::endl;
+                                               //std::cout << transform << std::endl;
+
+                                               it++;
+                                               billboard* newBB = new billboard(transform, texture,
+                                                               *it);
+                                               boost::shared_ptr<scenery> sceneItem(newBB);
+                                               objects.push_back(sceneItem);
+                                       }
+                               }
+                       }
+               }
+       }
+
+
        void loadFromFile()
        {
                std::string filePath = scene::getPathToResource(getName());
@@ -95,19 +439,32 @@ public:
                                {
                                        loadBox(maximumBounds, (*it).second);
                                }
-
-                               //for (i = rootObj.begin(); i != rootObj.end(); i++)
-                               //{
-                                       //sequences.insert(std::pair<std::string,sequence>((*i).first,
-                                                               //sequence((*i).second)));
-                               //}
+                               if ((it = rootObj.find("instructions")) != rootObj.end())
+                               {
+                                       loadInstructions((*it).second);
+                               }
                        }
                }
        }
 
+
+       void draw(scalar alpha)
+       {
+               scenery_list::iterator it;
+
+               for (it = objects.begin(); it != objects.end(); it++)
+               {
+                       //std::cout << "draw object";
+                       (*it)->draw(alpha);
+               }
+       }
+
+
        aabb playfieldBounds;
        aabb maximumBounds;
 
+       typedef std::vector<boost::shared_ptr<scenery> > scenery_list;
+       scenery_list objects;
 };
 
 
@@ -118,6 +475,8 @@ scene::scene(const std::string& name) :
 
 void scene::draw(scalar alpha)
 {
+       // pass through
+       impl->draw(alpha);
 }
 
 
index 0852f98e846af7a4be83ed55257157bbd288cef8..4a55c65eef9f7fa7871507b9dad8808a05e362d6 100644 (file)
 
 *******************************************************************************/
 
-#include <cassert>
-
-#include "mippleton.hh"
-#include "serializable.hh"
 #include "deserializer.hh"
-
+#include "mippleton.hh"
 #include "opengl.hh"
+#include "serializable.hh"
 
 #include "tilemap.hh"
 
@@ -154,9 +151,10 @@ tilemap::tilemap(const std::string& name) :
 }
 
 
-void tilemap::getTileCoords(unsigned index, scalar coords[8])
+bool tilemap::getTileCoords(unsigned index, scalar coords[8])
 {
-       assert(index < impl->tilesU_ * impl->tilesV_);
+       // make sure the index represents a real tile
+       if (index >= impl->tilesU_ * impl->tilesV_) return false;
 
        scalar w = 1.0 / scalar(impl->tilesU_);
        scalar h = 1.0 / scalar(impl->tilesV_);
@@ -169,26 +167,35 @@ void tilemap::getTileCoords(unsigned index, scalar coords[8])
        coords[5] = coords[1] + h;
        coords[6] = coords[0];
        coords[7] = coords[5];
+
+       return true;
 }
 
-void tilemap::getTileCoords(unsigned index, scalar coords[8], orientation what)
+bool tilemap::getTileCoords(unsigned index, scalar coords[8], orientation what)
 {
-       getTileCoords(index, coords);
-
-       if (what & flip)
+       if (getTileCoords(index, coords))
        {
-               coords[1] = coords[5];
-               coords[5] = coords[3];
-               coords[3] = coords[7];
-               coords[7] = coords[5];
-       }
-       if (what & reverse)
-       {
-               coords[0] = coords[2];
-               coords[2] = coords[6];
-               coords[4] = coords[6];
-               coords[6] = coords[0];
+               if (what & flip)
+               {
+                       // this looks kinda weird, but it's just swapping in a way that
+                       // doesn't require an intermediate variable
+                       coords[1] = coords[5];
+                       coords[5] = coords[3];
+                       coords[3] = coords[7];
+                       coords[7] = coords[5];
+               }
+               if (what & reverse)
+               {
+                       coords[0] = coords[2];
+                       coords[2] = coords[6];
+                       coords[4] = coords[6];
+                       coords[6] = coords[0];
+               }
+
+               return true;
        }
+
+       return false;
 }
 
 
index f2f76ab5fc8849f9b89e02b98ed69a48ef0b8acc..df8d9af842e1ed7224e65fea850067355b924b7c 100644 (file)
@@ -77,9 +77,10 @@ public:
         * two places and so on until all four coordinates are stored, therefore
         * requiring enough room for an array of eight scalars.  The winding of the
         * coordinates is always counter-clockwise (the GL default).
+        * @return True if index is valid, false otherwise.
         */
 
-       void getTileCoords(unsigned index, scalar coords[8]);
+       bool getTileCoords(unsigned index, scalar coords[8]);
 
 
        /**
@@ -87,9 +88,10 @@ public:
         * the texture coordinates.  This allows you to easily map a texture
         * backwards or upside-down.
         * @param what The orientation; can be flip, reverse, or flip_and_reverse.
+        * @return True if index is valid, false otherwise.
         */
 
-       void getTileCoords(unsigned index, scalar coords[8], orientation what);
+       bool getTileCoords(unsigned index, scalar coords[8], orientation what);
 
 
        static std::string getPathToResource(const std::string& name);
This page took 0.046752 seconds and 4 git commands to generate.