#ifndef DNLOAD_H
#define DNLOAD_H

/** \file
 * \brief Dynamic loader header stub.
 *
 * This file is automatically generated, do not modify.
 *
 * Include this file instead of the regular OpenGL et. al.
 */

#if !defined(USE_LD)
#if defined(__FreeBSD__) || defined(__linux__)
#if defined(__i386)
#include "dnload_elf32.h"
#else
#error "no dynamic loading procedure defined for current architecture"
#endif
#else
#error "no dynamic loading procedure defined for current operating system"
#endif
#endif

#if defined(USE_LD)
#if defined(WIN32)
#include "windows.h"
#include "GL/glew.h"
#include "GL/glu.h"
#include "SDL.h"
#elif defined(__APPLE__)
#include "GL/glew.h"
#include "GL/glu.h"
#include "SDL/SDL.h"
#else
#include "GL/glew.h"
#include "GL/glu.h"
#include "SDL.h"
#endif
#include "bsd_rand.h"
#else
/** \cond */
#define GL_GLEXT_PROTOTYPES
/** \endcond */
#include "GL/gl.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "SDL.h"
#include "asm_exit.h"
#endif

#if defined(GLEWAPIENTRY)
/** \cond */
#define DNLOADAPIENTRY GLEWAPIENTRY
/** \endcond */
#else
/** \cond */
#define DNLOADAPIENTRY
/** \endcond */
#endif

#if defined(WIN32)
/** \cond */
#define _USE_MATH_DEFINES
/** \endcond */
#endif

#include <math.h>

#if defined(__cplusplus)
extern "C" {
#endif

/** \brief Symbol table structure.
 *
 * Contains all the symbols required for dynamic linking.
 */
struct SymbolTableStruct
{
  int (*rand)(void);
  void (DNLOADAPIENTRY *glUseProgram)(GLuint);
  void (DNLOADAPIENTRY *glTexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
  void (DNLOADAPIENTRY *glDisable)(GLenum);
  void (DNLOADAPIENTRY *glGenTextures)(GLsizei, GLuint*);
  float (*tanhf)(float);
  void (*srand)(unsigned int);
  void (DNLOADAPIENTRY *glVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
  void (DNLOADAPIENTRY *glBindTexture)(GLenum, GLuint);
  void (DNLOADAPIENTRY *glLinkProgram)(GLuint);
  void (DNLOADAPIENTRY *glShaderSource)(GLuint, GLsizei, const GLchar**, const GLint*);
  GLint (DNLOADAPIENTRY *glGetUniformLocation)(GLuint, const GLchar*);
  void (DNLOADAPIENTRY *glRects)(GLshort, GLshort, GLshort, GLshort);
  SDL_Surface* (*SDL_SetVideoMode)(int, int, int, Uint32);
  void (DNLOADAPIENTRY *glBindFramebuffer)(GLenum, GLuint);
  void (DNLOADAPIENTRY *glDrawArrays)(GLenum, GLint, GLsizei);
  void (DNLOADAPIENTRY *glClearColor)(GLclampf, GLclampf, GLclampf, GLclampf);
  int (*SDL_ShowCursor)(int);
  void (DNLOADAPIENTRY *glUniform4fv)(GLint, GLsizei, const GLfloat*);
  int (*SDL_PollEvent)(SDL_Event*);
  void (DNLOADAPIENTRY *glClear)(GLbitfield);
  void (DNLOADAPIENTRY *glActiveTexture)(GLenum);
  void (DNLOADAPIENTRY *glEnableVertexAttribArray)(GLuint);
  GLint (DNLOADAPIENTRY *glGetAttribLocation)(GLuint, const GLchar*);
  void (DNLOADAPIENTRY *glUniform3fv)(GLint, GLsizei, const GLfloat*);
  void (DNLOADAPIENTRY *glAttachShader)(GLuint, GLuint);
  void (DNLOADAPIENTRY *glCompileShader)(GLuint);
  void (DNLOADAPIENTRY *glFramebufferTexture2D)(GLenum, GLenum, GLenum, GLuint, GLint);
  GLuint (DNLOADAPIENTRY *glCreateProgram)(void);
  void (DNLOADAPIENTRY *glTexImage3D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
  void (DNLOADAPIENTRY *glUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat*);
  void (DNLOADAPIENTRY *glViewport)(GLint, GLint, GLsizei, GLsizei);
  void (DNLOADAPIENTRY *glUniform3f)(GLint, GLfloat, GLfloat, GLfloat);
  void (DNLOADAPIENTRY *glTexImage2DMultisample)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean);
  void (*SDL_GL_SwapBuffers)(void);
  void (DNLOADAPIENTRY *glGenFramebuffers)(GLsizei, GLuint*);
  int (*SDL_Init)(Uint32);
  void (DNLOADAPIENTRY *glTexParameteri)(GLenum, GLenum, GLint);
  void (*SDL_PauseAudio)(int);
  void (DNLOADAPIENTRY *glUniform1f)(GLint, GLfloat);
  void (*SDL_Quit)(void);
  float (*acosf)(float);
  int (*SDL_OpenAudio)(SDL_AudioSpec*, SDL_AudioSpec*);
  GLuint (DNLOADAPIENTRY *glCreateShader)(GLenum);
  float (*powf)(float, float);
  void (DNLOADAPIENTRY *glUniform1i)(GLint, GLint);
  void *terminator;
};

/** Instance of the symbol table. */
static struct SymbolTableStruct g_sym =
{
  (int (*)(void))0xe83af065L,
  (void (DNLOADAPIENTRY *)(GLuint))0xcc55bb62L,
  (void (DNLOADAPIENTRY *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*))0xa259532bL,
  (void (DNLOADAPIENTRY *)(GLenum))0xb5f7c43,
  (void (DNLOADAPIENTRY *)(GLsizei, GLuint*))0x9bdd4fa3L,
  (float (*)(float))0x9ec2e83fL,
  (void (*)(unsigned int))0x6b699dd8,
  (void (DNLOADAPIENTRY *)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*))0xc443174aL,
  (void (DNLOADAPIENTRY *)(GLenum, GLuint))0x95e43fb9L,
  (void (DNLOADAPIENTRY *)(GLuint))0x133a35c5,
  (void (DNLOADAPIENTRY *)(GLuint, GLsizei, const GLchar**, const GLint*))0xc609c385L,
  (GLint (DNLOADAPIENTRY *)(GLuint, const GLchar*))0x25c12218,
  (void (DNLOADAPIENTRY *)(GLshort, GLshort, GLshort, GLshort))0xd419e20aL,
  (SDL_Surface* (*)(int, int, int, Uint32))0x39b85060,
  (void (DNLOADAPIENTRY *)(GLenum, GLuint))0xa0fdff6bL,
  (void (DNLOADAPIENTRY *)(GLenum, GLint, GLsizei))0xcb871c63L,
  (void (DNLOADAPIENTRY *)(GLclampf, GLclampf, GLclampf, GLclampf))0x8c118fbbL,
  (int (*)(int))0xb88bf697L,
  (void (DNLOADAPIENTRY *)(GLint, GLsizei, const GLfloat*))0x22b26935,
  (int (*)(SDL_Event*))0x64949d97,
  (void (DNLOADAPIENTRY *)(GLbitfield))0x1fd92088,
  (void (DNLOADAPIENTRY *)(GLenum))0xd7d4d450L,
  (void (DNLOADAPIENTRY *)(GLuint))0xe9e99723L,
  (GLint (DNLOADAPIENTRY *)(GLuint, const GLchar*))0xceb27dd0L,
  (void (DNLOADAPIENTRY *)(GLint, GLsizei, const GLfloat*))0x223459b4,
  (void (DNLOADAPIENTRY *)(GLuint, GLuint))0x30b3cfcf,
  (void (DNLOADAPIENTRY *)(GLuint))0xc5165dd3L,
  (void (DNLOADAPIENTRY *)(GLenum, GLenum, GLenum, GLuint, GLint))0x18781f65,
  (GLuint (DNLOADAPIENTRY *)(void))0x78721c3,
  (void (DNLOADAPIENTRY *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*))0xa25a536aL,
  (void (DNLOADAPIENTRY *)(GLint, GLsizei, GLboolean, const GLfloat*))0x50a8d153,
  (void (DNLOADAPIENTRY *)(GLint, GLint, GLsizei, GLsizei))0xecca892bL,
  (void (DNLOADAPIENTRY *)(GLint, GLfloat, GLfloat, GLfloat))0x4feb7742,
  (void (DNLOADAPIENTRY *)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean))0x732f22f8,
  (void (*)(void))0xda43e6eaL,
  (void (DNLOADAPIENTRY *)(GLsizei, GLuint*))0xb1503371L,
  (int (*)(Uint32))0x70d6574,
  (void (DNLOADAPIENTRY *)(GLenum, GLenum, GLint))0xdefef0c2L,
  (void (*)(int))0x29f14a4,
  (void (DNLOADAPIENTRY *)(GLint, GLfloat))0x4fe976c4,
  (void (*)(void))0x7eb657f3,
  (float (*)(float))0xf1ce8ee0L,
  (int (*)(SDL_AudioSpec*, SDL_AudioSpec*))0x46fd70c8,
  (GLuint (DNLOADAPIENTRY *)(GLenum))0x6b4ffac6,
  (float (*)(float, float))0x921b2a2eL,
  (void (DNLOADAPIENTRY *)(GLint, GLint))0x4fe976c7,
  NULL
};

/** \brief Perform init.
 *
 * \param screen_w Screen width definition.
 * \param screen_h Screen height definition.
 * \param flag_fullscreen Fullscreen flag definition.
 */
static void init(int screen_w, int screen_h, unsigned flag_fullscreen)
{
#if defined(USE_LD)
  SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
  SDL_SetVideoMode(screen_w, screen_h, 0, SDL_OPENGL | (flag_fullscreen ? SDL_FULLSCREEN : 0));

  {
    GLenum err = glewInit();

    if(GLEW_OK != err)
    {
      SDL_Quit();
      fprintf(stderr, "glewInit(): %s", glewGetErrorString(err));
      exit(1);
    }
  }

  g_sym.rand = bsd_rand;
  g_sym.glUseProgram = glUseProgram;
  g_sym.glTexImage2D = glTexImage2D;
  g_sym.glDisable = glDisable;
  g_sym.glGenTextures = glGenTextures;
  g_sym.tanhf = tanhf;
  g_sym.srand = bsd_srand;
  g_sym.glVertexAttribPointer = glVertexAttribPointer;
  g_sym.glBindTexture = glBindTexture;
  g_sym.glLinkProgram = glLinkProgram;
  g_sym.glShaderSource = glShaderSource;
  g_sym.glGetUniformLocation = glGetUniformLocation;
  g_sym.glRects = glRects;
  g_sym.SDL_SetVideoMode = SDL_SetVideoMode;
  g_sym.glBindFramebuffer = glBindFramebuffer;
  g_sym.glDrawArrays = glDrawArrays;
  g_sym.glClearColor = glClearColor;
  g_sym.SDL_ShowCursor = SDL_ShowCursor;
  g_sym.glUniform4fv = glUniform4fv;
  g_sym.SDL_PollEvent = SDL_PollEvent;
  g_sym.glClear = glClear;
  g_sym.glActiveTexture = glActiveTexture;
  g_sym.glEnableVertexAttribArray = glEnableVertexAttribArray;
  g_sym.glGetAttribLocation = glGetAttribLocation;
  g_sym.glUniform3fv = glUniform3fv;
  g_sym.glAttachShader = glAttachShader;
  g_sym.glCompileShader = glCompileShader;
  g_sym.glFramebufferTexture2D = glFramebufferTexture2D;
  g_sym.glCreateProgram = glCreateProgram;
  g_sym.glTexImage3D = glTexImage3D;
  g_sym.glUniformMatrix3fv = glUniformMatrix3fv;
  g_sym.glViewport = glViewport;
  g_sym.glUniform3f = glUniform3f;
  g_sym.glTexImage2DMultisample = glTexImage2DMultisample;
  g_sym.SDL_GL_SwapBuffers = SDL_GL_SwapBuffers;
  g_sym.glGenFramebuffers = glGenFramebuffers;
  g_sym.SDL_Init = SDL_Init;
  g_sym.glTexParameteri = glTexParameteri;
  g_sym.SDL_PauseAudio = SDL_PauseAudio;
  g_sym.glUniform1f = glUniform1f;
  g_sym.SDL_Quit = SDL_Quit;
  g_sym.acosf = acosf;
  g_sym.SDL_OpenAudio = SDL_OpenAudio;
  g_sym.glCreateShader = glCreateShader;
  g_sym.powf = powf;
  g_sym.glUniform1i = glUniform1i;
#else
  {
    void **iter = (void**)&g_sym;
    do {
      *iter = dnload_find_symbol(*(uint32_t*)iter);
      ++iter;
    } while(*iter);
  }

  g_sym.SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
  g_sym.SDL_SetVideoMode(screen_w, screen_h, 0, SDL_OPENGL | (flag_fullscreen ? SDL_FULLSCREEN : 0));
#endif
}

#if defined(__cplusplus)
}
#endif

#endif
