#include <SDL.h>
#if defined(WIN32)
#include <WTypes.h>
#include <WinGDI.h>
#endif
#if !defined(HAVE_GLES)
#include <GL/gl.h>
#include <gl\glu.h>            // Header File For The GLu32 Library
#else
#include <GLES/gl.h>
#include "eglport.h"
#endif
int   mapObject[41][41];
float mapBaseHeight[41][41];
float curX = 0.0f;
float curY = 0.0f;
float curZ = 0.0f;
float rotZ = 0.0f;
int isL, isR, isU, isD, isPU, isPD;
void DrawColourQuad( GLfloat x[], GLfloat y[], GLfloat z[], GLfloat r, GLfloat g, GLfloat b );
void initMap();
void DrawMapItem( int X, int Y );
int main (int argc, char *argv[])
{
    SDL_Surface* screen;
    int quit = 0;
    SDL_Event event;
  SDL_Init( SDL_INIT_VIDEO );
#if defined(HAVE_GLES)
  if (!EGL_Open())
        exit(1);
#endif
#if !defined(HAVE_GLES)
    screen = SDL_SetVideoMode( 800, 600, 0, SDL_HWSURFACE | SDL_OPENGL ); // | SDL_FULLSCREEN);
    glShadeModel(GL_SMOOTH);   			             // Enable Smooth Shading
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                // Black Background
    glClearDepth(1.0f);   					             // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);   			             // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);   				             // The Type Of Depth Testing To Do
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculations
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_BLEND);
    //glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
    //glEnable(GL_COLOR_MATERIAL);
    glMatrixMode(GL_MODELVIEW);   			             // Select The Modelview Matrix
    glLoadIdentity();   					             // Reset The Modelview Matrix
    glViewport(0,0,800,600);   		             // Reset The Current Viewport
    glMatrixMode(GL_PROJECTION);   		             // Select The Projection Matrix
    glLoadIdentity();   					             // Reset The Projection Matrix
    // Calculate The Aspect Ratio Of The Window
    gluPerspective(45.0f,800.0f/600.0f,0.1f,100.0f);
    glMatrixMode(GL_MODELVIEW);   			             // Select The Modelview Matrix
    glLoadIdentity();   					             // Reset The Modelview Matrix
#else
  screen = SDL_SetVideoMode( 800, 480, 0, SDL_SWSURFACE | SDL_FULLSCREEN );
    EGL_Init();
#endif
    initMap();
    isL = 0;
    isR = 0;
    isU = 0;
    isD = 0;
    isPU = 0;
    isPD = 0;
    // the event loop
    while( quit == 0 )
    {
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_KEYDOWN:
   	             if (event.key.keysym.sym == SDLK_ESCAPE)
   		             quit = 1;
   	             if( event.key.keysym.sym == SDLK_LEFT )
   		             isL = 1;
   	             if( event.key.keysym.sym == SDLK_RIGHT )
   		             isR = 1;
   	             if( event.key.keysym.sym == SDLK_UP )
   		             isU = 1;
   	             if( event.key.keysym.sym == SDLK_DOWN )
   		             isD = 1;
   	             if( event.key.keysym.sym == SDLK_PAGEUP )
   		             isPU = 1;
   	             if( event.key.keysym.sym == SDLK_PAGEDOWN )
   		             isPD = 1;
   	             break;
                case SDL_KEYUP:
   	             if( event.key.keysym.sym == SDLK_LEFT )
   		             isL = 0;
   	             if( event.key.keysym.sym == SDLK_RIGHT )
   		             isR = 0;
   	             if( event.key.keysym.sym == SDLK_UP )
   		             isU = 0;
   	             if( event.key.keysym.sym == SDLK_DOWN )
   		             isD = 0;
   	             if( event.key.keysym.sym == SDLK_PAGEUP )
   		             isPU = 0;
   	             if( event.key.keysym.sym == SDLK_PAGEDOWN )
   		             isPD = 0;
   	             break;
            }
        }
        if( isL != 0 )
            curX -= 0.1f;
        if( isR != 0 )
            curX += 0.1f;
        if( isU != 0 )
            curY -= 0.1f;
        if( isD != 0 )
            curY += 0.1f;
        if( isPU != 0 )
            curZ -= 0.1f;
        if( isPD != 0 )
            curZ += 0.1f;
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
        float iX;
        float iY;
        for( iY = -20.0f; iY <= 20.0f; iY += 1.0f )
        {
            for( iX = -20.0f; iX <= 20.0f; iX += 1.0f )
            {
 			DrawMapItem( (int)iX, (int)iY );
            }
        }
#if !defined(HAVE_GLES)
        SDL_GL_SwapBuffers();
#else
        EGL_SwapBuffers();
#endif
    }
#if defined(HAVE_GLES)
    EGL_Close();
#endif
    SDL_Quit();
    return 0;
}
void initMap()
{
    int iX;
    int iY;
    for( iY = 0; iY <= 40; iY++ )
    {
        for( iX = 0; iX <= 40; iX++ )
        {
		mapObject[iX][iY] = 0;
		mapBaseHeight[iX][iY] = 0;
        }
    }
  mapObject[20][20] = 1;
  mapObject[21][20] = 1;
    mapBaseHeight[21][22] = 0.6f;
    mapBaseHeight[21][23] = 0.7f;
    mapBaseHeight[21][24] = 0.6f;
  mapObject[22][24] = 2;
  mapBaseHeight[22][24] = 0.4f;
  mapObject[22][23] = 2;
  mapBaseHeight[22][23] = 0.2f;
  mapObject[22][22] = 2;
  mapObject[27][24] = 3;
  mapBaseHeight[27][24] = 0.4f;
  mapObject[27][23] = 4;
  mapBaseHeight[27][23] = 0.2f;
  mapObject[27][22] = 5;
}
void DrawColourQuad( GLfloat x[], GLfloat y[], GLfloat z[], GLfloat r, GLfloat g, GLfloat b )
{
#if !defined(HAVE_GLES)
  glBegin(GL_QUADS);
  glColor3f( r, g, b );
  glVertex3f( x[0], y[0], z[0] );
  glVertex3f( x[1], y[1], z[1] );
  glVertex3f( x[2], y[2], z[2] );
  glVertex3f( x[3], y[3], z[3] );
  glEnd();
#else
    GLfloat vtx1[] = {
        x[0], y[0], z[0],
        x[1], y[1], z[1],
        x[2], y[2], z[2],
        x[3], y[3], z[3]
    };
    GLfloat col1[] = {
        r, g, b, 1.0f,
        r, g, b, 1.0f,
        r, g, b, 1.0f,
        r, g, b, 1.0f
    };
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vtx1);
    glColorPointer(4, GL_FLOAT, 0, col1);
    glDrawArrays(GL_TRIANGLE_FAN,0,4);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
#endif
}
void DrawMapItem( int X, int Y )
{
    GLfloat qX[4] = { 0.0f, 1.0f, 1.0f, 0.0f };
    GLfloat qY[4] = { 1.0f, 1.0f, 0.0f, 0.0f };
    GLfloat qZ[4] = { -6.0f, -6.0f, -6.0f, -6.0f };
    glLoadIdentity();
    glTranslatef((float)X - curX, curY + (float)Y, curZ - 8.0f);
    /*
    qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20];
    qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20];
    qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
    qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
    DrawColourQuad( qX, qY, qZ, ((float)X + 20.0f)/40.0f, ((float)Y + 20.0f)/40.0f, 1.0f );
    */
  switch( mapObject[X+20][Y+20] )
  {
	case 0:
            qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20];
            qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20];
            qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
            qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
            DrawColourQuad( qX, qY, qZ, ((float)X + 20.0f)/40.0f, ((float)Y + 20.0f)/40.0f, 1.0f );
            if( mapBaseHeight[X+20][Y+20] != 0.0f )
            {
                qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = 0.0f;
                qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = 0.0f;
                qX[2] = 1.0f; qY[2] = 1.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
                qX[3] = 0.0f; qY[3] = 1.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
                DrawColourQuad( qX, qY, qZ, 0.2f, 0.2f, 0.2f );
                qX[0] = 1.0f; qY[0] = 0.0f; qZ[0] = 0.0f;
                qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = 0.0f;
                qX[2] = 1.0f; qY[2] = 1.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
                qX[3] = 1.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
                DrawColourQuad( qX, qY, qZ, 0.2f, 0.2f, 0.2f );
                qX[0] = 0.0f; qY[0] = 0.0f; qZ[0] = 0.0f;
                qX[1] = 1.0f; qY[1] = 0.0f; qZ[1] = 0.0f;
                qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
                qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
                DrawColourQuad( qX, qY, qZ, 0.4f, 0.4f, 0.4f );
                qX[0] = 0.0f; qY[0] = 0.0f; qZ[0] = 0.0f;
                qX[1] = 0.0f; qY[1] = 1.0f; qZ[1] = 0.0f;
                qX[2] = 0.0f; qY[2] = 1.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
                qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
                DrawColourQuad( qX, qY, qZ, 0.4f, 0.4f, 0.4f );
            }
  	break;
	case 1:
            qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20] + 0.2f;
            DrawColourQuad( qX, qY, qZ, 0.8f, 0.8f, 0.8f );
            /*
  	glColor3f(0.2f, 0.2f,0.2f);   			             // Set The Color To Blue One Time Only
  	glVertex3f( 0.0f, 1.0f, 0.0f);   	             // Top Left
  	glVertex3f( 1.0f, 1.0f, 0.0f);   	             // Top Right
  	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Right
  	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Left
  	glVertex3f( 1.0f, 0.0f, 0.0f);   	             // Top Left
  	glVertex3f( 1.0f, 1.0f, 0.0f);   	             // Top Right
  	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Right
  	glVertex3f( 1.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Left
  	glColor3f(0.4f, 0.4f,0.4f);   			             // Set The Color To Blue One Time Only
  	glVertex3f( 0.0f, 0.0f, 0.0f);   	             // Top Left
  	glVertex3f( 1.0f, 0.0f, 0.0f);   	             // Top Right
  	glVertex3f( 1.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Right
  	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Left
  	glVertex3f( 0.0f, 0.0f, 0.0f);   	             // Top Left
  	glVertex3f( 0.0f, 1.0f, 0.0f);   	             // Top Right
  	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Right
  	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 2.0f);   	             // Bottom Left
            */
  	break;
	case 2:
            /*
  	glColor3f(0.4f,0.4f,0.4f);
    	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Top Left
    	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Top Right
    	glVertex3f( 1.0f, 0.0f, mapBaseHeight[X+20][Y+20]);   	             // Bottom Right
    	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20]);   	             // Bottom Left
  	glColor3f(0.2f,0.2f,0.2f);
    	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Top Left
    	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Top Right
    	glVertex3f( 1.0f, 1.0f, 0.0f);   	             // Bottom Right
    	glVertex3f( 0.0f, 1.0f, 0.0f);   	             // Bottom Left
    	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Top Left
    	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20]);   	             // Top Right
    	glVertex3f( 0.0f, 0.0f, 0.0f);   	             // Bottom Right
    	glVertex3f( 0.0f, 1.0f, 0.0f);   	             // Bottom Left
            */
            qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
            qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
            DrawColourQuad( qX, qY, qZ, 0.4f, 0.4f, 0.4f );
  	break;
	case 3:
            /*
  	glColor3f(0.4f,0.4f,0.4f);
    	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Top Left
    	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20]);   	             // Top Right
    	glVertex3f( 1.0f, 0.0f, mapBaseHeight[X+20][Y+20]);   	             // Bottom Right
    	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Bottom Left
            */
            qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20];
            qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
            qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20] + 0.2f;
            DrawColourQuad( qX, qY, qZ, 0.4f, 0.4f, 0.4f );
  	break;
	case 4:
            /*
  	glColor3f(0.4f,0.4f,0.4f);
    	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20]);   	             // Top Left
    	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Top Right
    	glVertex3f( 1.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Bottom Right
    	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20]);   	             // Bottom Left
            */
            qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20];
            qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
            DrawColourQuad( qX, qY, qZ, 0.4f, 0.4f, 0.4f );
  	break;
	case 5:
            /*
  	glColor3f(0.4f,0.4f,0.4f);
    	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20]);   	             // Top Left
    	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20]);   	             // Top Right
    	glVertex3f( 1.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Bottom Right
    	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20] + 0.2f);   	             // Bottom Left
            */
            qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20];
            qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20];
            qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20] + 0.2f;
            qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20] + 0.2f;
            DrawColourQuad( qX, qY, qZ, 0.4f, 0.4f, 0.4f );
  	break;
	case 6:
            /*
  	glColor3f(0.4f,0.4f,0.4f);
    	glVertex3f( 0.0f, 1.0f, mapBaseHeight[X+20][Y+20]);   	             // Top Left
    	glVertex3f( 1.0f, 1.0f, mapBaseHeight[X+20][Y+20]);   	             // Top Right
    	glVertex3f( 1.0f, 0.0f, mapBaseHeight[X+20][Y+20]);   	             // Bottom Right
    	glVertex3f( 0.0f, 0.0f, mapBaseHeight[X+20][Y+20]);   	             // Bottom Left
            */
            qX[0] = 0.0f; qY[0] = 1.0f; qZ[0] = mapBaseHeight[X+20][Y+20];
            qX[1] = 1.0f; qY[1] = 1.0f; qZ[1] = mapBaseHeight[X+20][Y+20];
            qX[2] = 1.0f; qY[2] = 0.0f; qZ[2] = mapBaseHeight[X+20][Y+20];
            qX[3] = 0.0f; qY[3] = 0.0f; qZ[3] = mapBaseHeight[X+20][Y+20];
            DrawColourQuad( qX, qY, qZ, 0.4f, 0.4f, 0.4f );
  	break;
  }
}