Enable FBO support; fix a couple bugs.

Enable framebuffer object support.  I'm starting to see the value of
GLEW, but the implementations available don't handle GLES very well.  A
primitive attempt at cross-platform compatibility at the source code
level was attempted, but the Correct Solution is runtime adaptation.

Fixed a bug in PCM.cpp; it now properly scales int16_t values to the
range -1.0 - 1.0.

Fixed a bug in Renderable.cpp; 'size' can be zero, leading to an attempt
to allocate and render a buffer of zero size.  While the code correctly
handles zero-sized buffers, it's better to avoid it entirely.
diff --git a/src/libprojectM/PCM.cpp b/src/libprojectM/PCM.cpp
index 1caebd4..03aafe9 100644
--- a/src/libprojectM/PCM.cpp
+++ b/src/libprojectM/PCM.cpp
@@ -146,8 +146,8 @@
 
   for (i = 0;  i < samples;  ++i) {
     j = i + start;
-    PCMd[0][j % maxsamples] = (pcm_data[i * 2 + 0] / 16384.0);
-    PCMd[1][j % maxsamples] = (pcm_data[i * 2 + 1] / 16384.0);
+    PCMd[0][j % maxsamples] = (pcm_data[i * 2 + 0] / 32768.0);
+    PCMd[1][j % maxsamples] = (pcm_data[i * 2 + 1] / 32768.0);
   }
 
   start = (start + samples) % maxsamples;
@@ -172,8 +172,8 @@
   for (i = 0;  i < samples; i++) {
     j = i + start;
     if (PCMdata[0][i] != 0  &&  PCMdata[1][i] != 0) {
-      PCMd[0][j % maxsamples] = (PCMdata[0][i] / 16384.0);
-      PCMd[1][j % maxsamples] = (PCMdata[1][i] / 16384.0);
+      PCMd[0][j % maxsamples] = (PCMdata[0][i] / 32768.0);
+      PCMd[1][j % maxsamples] = (PCMdata[1][i] / 32768.0);
     } else {
       PCMd[0][j % maxsamples] = (float) 0;
       PCMd[1][j % maxsamples] = (float) 0;
diff --git a/src/libprojectM/Renderer/FBO.cpp b/src/libprojectM/Renderer/FBO.cpp
index fe86e8f..06aa4fd 100644
--- a/src/libprojectM/Renderer/FBO.cpp
+++ b/src/libprojectM/Renderer/FBO.cpp
@@ -24,6 +24,7 @@
  * Render this methods
  */
 #include <stdio.h>
+#include <string.h>
 //#include <GL/gl.h>
 #include <iostream>
 #include "Common.hpp"
@@ -39,13 +40,13 @@
   if (useFBO)
   {
     glDeleteTextures (1, &this->textureID[1]);
-    glDeleteRenderbuffersEXT (1,  &this->depthb[0]);
-    glDeleteFramebuffersEXT (1, &this->fbuffer[0]);
+    glDeleteRenderbuffers (1,  &this->depthb[0]);
+    glDeleteFramebuffers (1, &this->fbuffer[0]);
     if (renderToTexture)
     {
       glDeleteTextures (1, &this->textureID[2]);
-      glDeleteRenderbuffersEXT (1,  &this->depthb[1]);
-      glDeleteFramebuffersEXT (1, &this->fbuffer[1]);
+      glDeleteRenderbuffers (1,  &this->depthb[1]);
+      glDeleteFramebuffers (1, &this->fbuffer[1]);
     }
   }
 #endif
@@ -60,13 +61,13 @@
 
     GLuint   fb2, depth_rb2;
 
-    glGenFramebuffersEXT (1, &fb2);
-    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fb2);
-    glGenRenderbuffersEXT (1, &depth_rb2);
-    glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, depth_rb2);
+    glGenFramebuffers (1, &fb2);
+    glBindFramebuffer (GL_FRAMEBUFFER, fb2);
+    glGenRenderbuffers (1, &depth_rb2);
+    glBindRenderbuffer (GL_RENDERBUFFER, depth_rb2);
 
-    glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize );
-    glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb2);
+    glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, this->texsize,this->texsize );
+    glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb2);
     this->fbuffer[1] = fb2;
     this->depthb[1]=  depth_rb2;
     glGenTextures (1, &this->textureID[2]);
@@ -74,9 +75,14 @@
     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+#ifdef USE_GLES1
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-    glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->textureID[2], 0);
+#endif
+    glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->textureID[2], 0);
     return this->textureID[2];
   }
 #endif
@@ -94,25 +100,49 @@
   this->texsize = texsize;
 
 #ifdef USE_FBO
-  // Forceably disable FBO if user requested it but the video card / driver lacks
+  // Forcibly disable FBO if user requested it but the video card / driver lacks
   // the appropraite frame buffer extension.
-  useFBO = !!strstr ((char const *) glGetString (GL_EXTENSIONS),
+
 #ifdef USE_GLES1
-                     "GL_OES_framebuffer_object"
+  /*
+   * FBO support is never part of GLES1 core; check for extension.
+   */
+  useFBO = !!strstr ((char const *) glGetString (GL_EXTENSIONS),
+                     "GL_OES_framebuffer_object");
 #else
-                     "GL_EXT_framebuffer_object"
-#endif
-                   );
+  /*
+   * If GL 3.0 or later is in scope, then framebuffer object support is present
+   * by default, and we just use the user's preference.
+   */
+  {
+    long        majorvers;
+    char const  *glvers;
+    char        *endptr;
+
+    glvers = glGetString (GL_VERSION);
+    majorvers = strtol (glvers, &endptr, 10);
+    if (endptr == glvers  ||  *endptr != '.') {
+      /*  Unparseable version number; force extension check.  */
+      majorvers = 0;
+    }
+    if (majorvers < 3) {
+      /*  GL 3.0 not in scope; check for FBO support by extension.  */
+      useFBO = !!strstr ((char const *) glGetString (GL_EXTENSIONS),
+                         "GL_EXT_framebuffer_object");
+    }
+  }
+#endif  /*  USE_GLES1  */
+
   if (useFBO)
   {
     GLuint   fb,  depth_rb, rgba_tex,  other_tex;
-    glGenFramebuffersEXT (1, &fb);
-    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fb);
+    glGenFramebuffers (1, &fb);
+    glBindFramebuffer (GL_FRAMEBUFFER, fb);
 
-    glGenRenderbuffersEXT (1, &depth_rb);
-    glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, depth_rb);
-    glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize );
-    glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
+    glGenRenderbuffers (1, &depth_rb);
+    glBindRenderbuffer (GL_RENDERBUFFER, depth_rb);
+    glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, this->texsize,this->texsize );
+    glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb);
     this->fbuffer[0] = fb;
     this->depthb[0]=  depth_rb;
 
@@ -121,9 +151,14 @@
     glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    //glGenerateMipmapEXT (GL_TEXTURE_2D);
+    //glGenerateMipmap (GL_TEXTURE_2D);
+#ifdef USE_GLES1
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#endif
 
 
 
@@ -132,21 +167,26 @@
     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    //glGenerateMipmapEXT (GL_TEXTURE_2D);
+    //glGenerateMipmap (GL_TEXTURE_2D);
+#ifdef USE_GLES1
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#endif
 
 
 
-    glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, rgba_tex, 0);
+    glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgba_tex, 0);
     this->textureID[0] = rgba_tex;
     this->textureID[1] = other_tex;
 
-    GLenum status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
+    GLenum status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
 
-    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
+    glBindFramebuffer (GL_FRAMEBUFFER, 0);
 
-    if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
+    if (status == GL_FRAMEBUFFER_COMPLETE) {
       return;
     }
     std::cerr << "[projecM] warning: FBO support not detected. Using fallback." << std::endl;
@@ -232,7 +272,7 @@
 #ifdef USE_FBO
   if (this->useFBO)
   {
-    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, this->fbuffer[0]);
+    glBindFramebuffer (GL_FRAMEBUFFER, this->fbuffer[0]);
   }
 #endif
 }
@@ -248,7 +288,7 @@
     glCopyTexSubImage2D (GL_TEXTURE_2D,
                          0, 0, 0, 0, 0,
                          this->texsize, this->texsize);
-    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
+    glBindFramebuffer (GL_FRAMEBUFFER, 0);
     return;
   }
 #endif
diff --git a/src/libprojectM/Renderer/FBO.hpp b/src/libprojectM/Renderer/FBO.hpp
index 21f13ec..5eb90e3 100644
--- a/src/libprojectM/Renderer/FBO.hpp
+++ b/src/libprojectM/Renderer/FBO.hpp
@@ -46,6 +46,8 @@
 #endif
 #endif
 
+#include "fbodefs.h"
+
 
 typedef enum {
   SCALE_NEAREST,
diff --git a/src/libprojectM/Renderer/Renderable.cpp b/src/libprojectM/Renderer/Renderable.cpp
index 224f846..8e513c5 100644
--- a/src/libprojectM/Renderer/Renderable.cpp
+++ b/src/libprojectM/Renderer/Renderable.cpp
@@ -301,25 +301,27 @@
   {
     int size = x_num * y_num ;
 
-    floatPair *points = new float[size][2];
+    if (size) {
+      floatPair *points = new float[size][2];
 
-    for (int x=0;x<(int)x_num;x++)
-    {
-      for(int y=0;y<(int)y_num;y++)
+      for (int x=0;x<(int)x_num;x++)
       {
-        float lx, ly, lz;
-        lx = x_offset+x*intervalx;
-        ly = y_offset+y*intervaly;
+        for(int y=0;y<(int)y_num;y++)
+        {
+          float lx, ly, lz;
+          lx = x_offset+x*intervalx;
+          ly = y_offset+y*intervaly;
 
-        points[(x * (int)y_num) + y][0] = lx;
-        points[(x * (int)y_num) + y][1] = ly;
+          points[(x * (int)y_num) + y][0] = lx;
+          points[(x * (int)y_num) + y][1] = ly;
+        }
       }
+
+      glVertexPointer(2,GL_FLOAT,0,points);
+      glDrawArrays(GL_POINTS,0,size);
+
+      delete[] points;
     }
-
-    glVertexPointer(2,GL_FLOAT,0,points);
-    glDrawArrays(GL_POINTS,0,size);
-
-    delete[] points;
   }
 }
 
diff --git a/src/libprojectM/Renderer/Renderer.cpp b/src/libprojectM/Renderer/Renderer.cpp
index 0e72cb9..78c1501 100644
--- a/src/libprojectM/Renderer/Renderer.cpp
+++ b/src/libprojectM/Renderer/Renderer.cpp
@@ -1,4 +1,5 @@
 #include "Renderer.hpp"
+#include "fbodefs.h"
 #include "wipemalloc.h"
 #include "math.h"
 #include "Common.hpp"
@@ -219,10 +220,11 @@
   //video texture memory and render fullscreen.
 
   /** Reset the viewport size */
+
 #ifdef USE_FBO
   if (renderTarget->renderToTexture)
   {
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->renderTarget->fbuffer[1]);
+    glBindFramebuffer(GL_FRAMEBUFFER, this->renderTarget->fbuffer[1]);
     glViewport(0, 0, this->renderTarget->texsize, this->renderTarget->texsize);
   }
   else
@@ -265,7 +267,7 @@
 
 #ifdef USE_FBO
   if (renderTarget->renderToTexture)
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 #endif
 }
 
diff --git a/src/libprojectM/Renderer/fbodefs.h b/src/libprojectM/Renderer/fbodefs.h
new file mode 100644
index 0000000..e7dfa7c
--- /dev/null
+++ b/src/libprojectM/Renderer/fbodefs.h
@@ -0,0 +1,94 @@
+/**
+ * projectM -- Milkdrop-esque visualisation SDK
+ * Copyright (C)2003-2007 projectM Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * See 'LICENSE.txt' included within this release
+ *
+ */
+/**
+ * $Id: $
+ *
+ */
+#ifndef _FBODEFS_H
+#define _FBODEFS_H
+
+
+#if defined (USE_FBO)
+
+#if defined (USE_GLES1)
+
+/*
+ * Map OES API names to GL names.
+ */
+#define GL_FRAMEBUFFER                                    GL_FRAMEBUFFER_OES
+#define GL_RENDERBUFFER                                   GL_RENDERBUFFER_OES
+#define GL_RGBA4                                          GL_RGBA4_OES
+#define GL_RGB5_A1                                        GL_RGB5_A1_OES
+#define GL_RGB565                                         GL_RGB565_OES
+#define GL_DEPTH_COMPONENT16                              GL_DEPTH_COMPONENT16_OES
+#define GL_RENDERBUFFER_WIDTH                             GL_RENDERBUFFER_WIDTH_OES
+#define GL_RENDERBUFFER_HEIGHT                            GL_RENDERBUFFER_HEIGHT_OES
+#define GL_RENDERBUFFER_INTERNAL_FORMAT                   GL_RENDERBUFFER_INTERNAL_FORMAT_OES
+#define GL_RENDERBUFFER_RED_SIZE                          GL_RENDERBUFFER_RED_SIZE_OES
+#define GL_RENDERBUFFER_GREEN_SIZE                        GL_RENDERBUFFER_GREEN_SIZE_OES
+#define GL_RENDERBUFFER_BLUE_SIZE                         GL_RENDERBUFFER_BLUE_SIZE_OES
+#define GL_RENDERBUFFER_ALPHA_SIZE                        GL_RENDERBUFFER_ALPHA_SIZE_OES
+#define GL_RENDERBUFFER_DEPTH_SIZE                        GL_RENDERBUFFER_DEPTH_SIZE_OES
+#define GL_RENDERBUFFER_STENCIL_SIZE                      GL_RENDERBUFFER_STENCIL_SIZE_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE             GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME             GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL           GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE   GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES
+#define GL_COLOR_ATTACHMENT0                              GL_COLOR_ATTACHMENT0_OES
+#define GL_DEPTH_ATTACHMENT                               GL_DEPTH_ATTACHMENT_OES
+#define GL_STENCIL_ATTACHMENT                             GL_STENCIL_ATTACHMENT_OES
+#define GL_FRAMEBUFFER_COMPLETE                           GL_FRAMEBUFFER_COMPLETE_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT              GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT      GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS              GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS                 GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES
+#define GL_FRAMEBUFFER_UNSUPPORTED                        GL_FRAMEBUFFER_UNSUPPORTED_OES
+#define GL_FRAMEBUFFER_BINDING                            GL_FRAMEBUFFER_BINDING_OES
+#define GL_RENDERBUFFER_BINDING                           GL_RENDERBUFFER_BINDING_OES
+#define GL_MAX_RENDERBUFFER_SIZE                          GL_MAX_RENDERBUFFER_SIZE_OES
+#define GL_INVALID_FRAMEBUFFER_OPERATION                  GL_INVALID_FRAMEBUFFER_OPERATION_OES
+
+#define glIsRenderbuffer                      glIsRenderbufferOES
+#define glBindRenderbuffer                    glBindRenderbufferOES
+#define glDeleteRenderbuffers                 glDeleteRenderbuffersOES
+#define glGenRenderbuffers                    glGenRenderbuffersOES
+#define glRenderbufferStorage                 glRenderbufferStorageOES
+#define glGetRenderbufferParameteriv          glGetRenderbufferParameterivOES
+#define glIsFramebuffer                       glIsFramebufferOES
+#define glBindFramebuffer                     glBindFramebufferOES
+#define glDeleteFramebuffers                  glDeleteFramebuffersOES
+#define glGenFramebuffers                     glGenFramebuffersOES
+#define glCheckFramebufferStatus              glCheckFramebufferStatusOES
+#define glFramebufferRenderbuffer             glFramebufferRenderbufferOES
+#define glFramebufferTexture2D                glFramebufferTexture2DOES
+#define glGetFramebufferAttachmentParameteriv glGetFramebufferAttachmentParameterivOES
+#define glGenerateMipmap                      glGenerateMipmapOES
+
+#elif !defined (GL_VERSION_3_0)
+
+/*
+ * FIXME: Do a complete mapping from *EXT and/or *ARB API names.
+ */
+
+#endif  /*  GL_VERSION_3_0  */
+#endif  /*  USE_FBO  */
+
+#endif  /*  _FBODEFS_H  */