diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2015-09-24 17:52:07 -0400 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2015-09-24 17:52:07 -0400 |
commit | 144d3d5f39cb2cc9088fade10c6aefb9f79c9665 (patch) | |
tree | 8d4493a0b2d0e04ad49b630862e03d48e7fcb9b5 /src/ui.cpp | |
parent | 06f9901eb633fe9f15b2d9ddafdbf55725634481 (diff) |
good stuff
Diffstat (limited to 'src/ui.cpp')
-rw-r--r-- | src/ui.cpp | 163 |
1 files changed, 108 insertions, 55 deletions
@@ -1,24 +1,32 @@ #include <ui.h> -#include <world.h> -#include <ft2build.h> +#include <world.h> // World-switching stuff +#include <ft2build.h> // FreeType stuff #include FT_FREETYPE_H -#define SDL_KEY e.key.keysym.sym +#define SDL_KEY e.key.keysym.sym // Keeps the code neater :) -extern Player *player; -extern World *currentWorld; +extern Player *player; // 'player' should be (must be) defined in main.cpp +extern World *currentWorld; // should/must also be defined in main.cpp -static FT_Library ftl; +static FT_Library ftl; // Variables for the FreeType library and stuff static FT_Face ftf; static GLuint ftex; -static unsigned int fontSize; + +static bool dialogBoxExists=false; +static const char *dialogBoxText=NULL; namespace ui { + bool debug=false; + unsigned int fontSize; + /* + * initFonts(), setFontFace(), and setFontSize() are pretty self-explanatory + */ void initFonts(void){ if(FT_Init_FreeType(&ftl)){ std::cout<<"Error! Couldn't initialize freetype."<<std::endl; abort(); } + fontSize=12; // to be safe } void setFontFace(const char *ttf){ if(FT_New_Face(ftl,ttf,0,&ftf)){ @@ -30,51 +38,75 @@ namespace ui { fontSize=size; FT_Set_Pixel_Sizes(ftf,0,fontSize); } + float putChar(float x,float y,char c){ + unsigned int j; + char *buf; + float w,h; + // Load the first/next character (if possible) + if(FT_Load_Char(ftf,c,FT_LOAD_RENDER)){ + std::cout<<"Error! Unsupported character "<<c<<" ("<<(int)c<<")."<<std::endl; + abort(); + } + // Load the bitmap with OpenGL + glActiveTexture(GL_TEXTURE0); + glGenTextures(1,&ftex); + glBindTexture(GL_TEXTURE_2D,ftex); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + /* + * ftf->glyph->bitmap.buffer simply stores a bitmap of the character, + * and if OpenGL tries to load it directly it'll mistake it as a simple + * red on black texture. Here we allocate enough space to convert this + * bitmap to an RGBA-type buffer, also making the text white on black. + * + * TODO: allow different colors + */ + buf=(char *)malloc(ftf->glyph->bitmap.width*ftf->glyph->bitmap.rows*4); + for(j=0;j<ftf->glyph->bitmap.width*ftf->glyph->bitmap.rows;j++){ + buf[j*4]=255; + buf[j*4+1]=255; + buf[j*4+2]=255; + buf[j*4+3]=ftf->glyph->bitmap.buffer[j]?255:0; + } + glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ftf->glyph->bitmap.width,ftf->glyph->bitmap.rows,0,GL_RGBA,GL_UNSIGNED_BYTE,buf); + // Draw the texture and move the cursor + w=ftf->glyph->bitmap.width; + h=ftf->glyph->bitmap.rows; + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,ftex); + glBegin(GL_QUADS); + glColor3ub(255,255,255); + glTexCoord2f(0,1);glVertex2f(x,y); + glTexCoord2f(1,1);glVertex2f(x+w,y); + glTexCoord2f(1,0);glVertex2f(x+w,y+h); + glTexCoord2f(0,0);glVertex2f(x,y+h); + glEnd(); + glDisable(GL_TEXTURE_2D); + // Free the RGBA buffer and the OpenGL texture + free(buf); + glDeleteTextures(1,&ftex); + return w; + } void putString(const float x,const float y,const char *s){ unsigned int i=0,j; - float xo=x,yo=y,w,h; - char *buf; + float xo=x,yo=y; do{ - if(FT_Load_Char(ftf,s[i],FT_LOAD_RENDER)){ - std::cout<<"Error! Unsupported character "<<s[i]<<" ("<<(int)s[i]<<")."<<std::endl; - return; - } - glActiveTexture(GL_TEXTURE0); - glGenTextures(1,&ftex); - glBindTexture(GL_TEXTURE_2D,ftex); - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glPixelStorei(GL_UNPACK_ALIGNMENT,1); - buf=(char *)malloc(ftf->glyph->bitmap.width*ftf->glyph->bitmap.rows*4); - for(j=0;j<ftf->glyph->bitmap.width*ftf->glyph->bitmap.rows;j++){ - buf[j*4]=255; - buf[j*4+1]=255; - buf[j*4+2]=255; - buf[j*4+3]=ftf->glyph->bitmap.buffer[j]?255:0; + if(s[i]=='\n'){ + yo-=fontSize*1.15; + xo=x; + }else if(s[i]==' '){ + xo+=fontSize/2; + }else{ + xo+=putChar(xo,yo,s[i])+fontSize*.1; } - glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ftf->glyph->bitmap.width,ftf->glyph->bitmap.rows,0,GL_RGBA,GL_UNSIGNED_BYTE,buf); - w=ftf->glyph->bitmap.width; - h=ftf->glyph->bitmap.rows; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,ftex); - glBegin(GL_QUADS); - glColor3ub(255,255,255); - glTexCoord2f(0,1);glVertex2f(xo,yo); - glTexCoord2f(1,1);glVertex2f(xo+w,yo); - glTexCoord2f(1,0);glVertex2f(xo+w,yo+h); - glTexCoord2f(0,0);glVertex2f(xo,yo+h); - glEnd(); - glDisable(GL_TEXTURE_2D); - xo+=w; - free(buf); - glDeleteTextures(1,&ftex); }while(s[i++]); } - void putText(const float x,const float y,const char *str,...){ - va_list args; - char *buf; + void putText(const float x,const float y,const char *str,...){ // putText() simply runs 'str' and the extra arguments though + va_list args; // vsnprintf(), which'll store the complete string to a buffer + char *buf; // that's then passed to putString() buf=(char *)calloc(128,sizeof(char)); va_start(args,str); vsnprintf(buf,128,str,args); @@ -82,6 +114,17 @@ namespace ui { putString(x,y,buf); free(buf); } + void dialogBox(const char *text){ + dialogBoxExists=true; + dialogBoxText=text; + } + void draw(void){ + if(dialogBoxExists){ + glColor3ub(0,0,0); + glRectf(player->loc.x-SCREEN_WIDTH/2,SCREEN_HEIGHT,player->loc.x+SCREEN_WIDTH/2,SCREEN_HEIGHT-SCREEN_HEIGHT/4); + putString(player->loc.x-SCREEN_WIDTH/2,SCREEN_HEIGHT-fontSize,dialogBoxText); + } + } void handleEvents(void){ SDL_Event e; while(SDL_PollEvent(&e)){ @@ -90,21 +133,31 @@ namespace ui { gameRunning=false; break; case SDL_KEYDOWN: - if(SDL_KEY==SDLK_ESCAPE)gameRunning=false; - if(SDL_KEY==SDLK_a){ + if(SDL_KEY==SDLK_ESCAPE)gameRunning=false; // Exit the game with ESC + if(SDL_KEY==SDLK_a){ // Move left player->vel.x=-.15; - currentWorld=currentWorld->goWorldLeft(&player->loc,player->width); + currentWorld=currentWorld->goWorldLeft(player); } - if(SDL_KEY==SDLK_d){ + if(SDL_KEY==SDLK_d){ // Move right player->vel.x=.15; - currentWorld=currentWorld->goWorldRight(&player->loc,player->width); + currentWorld=currentWorld->goWorldRight(player); + } + if(SDL_KEY==SDLK_SPACE)player->vel.y=.25; // Jump + if(SDL_KEY==SDLK_i)currentWorld=currentWorld->goWorldBack(player); // Go back a layer if possible + if(SDL_KEY==SDLK_k)currentWorld=currentWorld->goWorldFront(player); // Go forward a layer if possible + if(SDL_KEY==SDLK_F3)debug^=true; + + // TEMPORARY UNTIL MOUSE + if(SDL_KEY==SDLK_t){ + if(dialogBoxExists){ + dialogBoxExists=false; + dialogBoxText=NULL; + }else dialogBox("Hello"); } - if(SDL_KEY==SDLK_SPACE)player->vel.y=.25; - if(SDL_KEY==SDLK_i)currentWorld=currentWorld->goWorldBack(&player->loc,player->width); - if(SDL_KEY==SDLK_k)currentWorld=currentWorld->goWorldFront(&player->loc,player->width); + break; case SDL_KEYUP: - if(SDL_KEY==SDLK_a)player->vel.x=0; + if(SDL_KEY==SDLK_a)player->vel.x=0; // Stop the player if movement keys are released if(SDL_KEY==SDLK_d)player->vel.x=0; break; default: |