Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <utils/font.hpp>
- //this is where the actual default font data is
- #define _UTILS_FONT_CPP
- #include <utils/_font_tables.h>
- #undef _UTILS_FONT_CPP
- font8x8::font8x8(SDL_Renderer* renderer,
- SDL_Color background,
- SDL_Color text,
- const Uint8* table)
- {
- if(renderer == nullptr) throw "renderer = nullptr";
- if(table == nullptr) throw "table = nullptr";
- _renderer = renderer;
- //8-bit indexed, though only the first 2 palette colors are used
- //(also, for 128 8x8 chars, a surface size of 128x64 is used)
- _fontSurface = SDL_CreateRGBSurfaceWithFormat(0,128,64,8,SDL_PIXELFORMAT_INDEX8);
- if(_fontSurface == nullptr){
- throw SDL_GetError(); //(_valid should already be false at this point)
- }
- //generate pixel data from font data
- if(SDL_LockSurface(_fontSurface)){ //make sure i have safe access to pixel data
- _freeSurfaceSafely();
- throw SDL_GetError();
- }
- Uint8* table_copy = (Uint8*) table; //otherwise i can't increment the pointer
- Uint8* pixels = (Uint8*) _fontSurface->pixels;
- for(int yi=0; yi<64; yi+=8){ //for each char vertically
- for(int xi=0; xi<128; xi+=8){ //for each char horizontally
- int charPos = xi + yi*128;
- for(int ri=0; ri<8; ++ri){ //for each row in current char
- Uint8 row = *(table_copy++);
- int rowPos = charPos + ri*128;
- pixels[rowPos++] = (row>>0)&1; //each byte is a char's row (8 pixels)
- pixels[rowPos++] = (row>>1)&1;
- pixels[rowPos++] = (row>>2)&1;
- pixels[rowPos++] = (row>>3)&1;
- pixels[rowPos++] = (row>>4)&1;
- pixels[rowPos++] = (row>>5)&1;
- pixels[rowPos++] = (row>>6)&1;
- pixels[rowPos++] = (row>>7)&1;
- }
- }
- }
- SDL_UnlockSurface(_fontSurface); //can't error
- //initialize palette to a user-defined color, and create font texture
- _valid = SDL_TRUE; //(_valid will be set back to false if setPalette fails)
- setPalette( background, text );
- }
- void font8x8::setPalette(SDL_Color background, SDL_Color text){
- if(!_valid) throw "invalid font";
- //the texture has be remade once the palette colors are modified
- _freeTextureSafely();
- //out of the 256 possible palette colors for 8-bit indexed, i'm only using 2
- _palette[0] = background;
- _palette[1] = text;
- if(SDL_LockSurface(_fontSurface)){
- _freeSurfaceSafely();
- _valid = SDL_FALSE;
- throw SDL_GetError();
- }
- //'replace 2 palette colors, starting at index 0'
- if(SDL_SetPaletteColors(_fontSurface->format->palette, _palette, 0, 2)){
- _freeSurfaceSafely();
- _valid = SDL_FALSE;
- throw SDL_GetError();
- }
- SDL_UnlockSurface(_fontSurface); //can't error
- _fontTexture = SDL_CreateTextureFromSurface(_renderer, _fontSurface);
- if(_fontTexture == nullptr){
- _valid = SDL_FALSE;
- throw SDL_GetError();
- }
- }
- void font8x8::putCharRaw(char chr, int x, int y){
- if(!_valid) throw "invalid font";
- //char 127 is treated as 'transparent', so don't draw anything
- if((chr&=127) == 127) return;
- SDL_Rect sourceRect;
- //position inside the font sprite sheet thing
- sourceRect.x = (chr&15)*8; //for a total of 16 columns, scaled by 8 pixels
- sourceRect.y = (chr>>4)*8; //for a total of 8 rows, scaled by 8 pixels
- sourceRect.w = 8; //source texture area should always be 8x8
- sourceRect.h = 8;
- //position with regard to the render target (usually the window itself)
- _lastChar.x = x;
- _lastChar.y = y;
- //_lastChar.<w/h> is in a union with _scale.<x/y>...
- //_lastChar.w = _scale.x; ...therefore this is redundant
- //_lastChar.h = _scale.y;
- SDL_RenderCopy(_renderer, _fontTexture, &sourceRect, &_lastChar);
- }
- void font8x8::printRaw(const std::string& txt, int x, int y){
- if(!_valid) throw "invalid font";
- int startX = x; //used for newline chars
- size_t length = txt.length();
- for(size_t i=0; i<length; ++i){
- char chr = txt.at(i)&127;
- switch(chr){
- //move back by 1 char
- case '\b': x -= _scale.x; break;
- //reset x, AND move down by 1 char
- case '\n': x = startX; SDL_FALLTHROUGH;
- //move down by 1 char
- case '\f': y += _scale.y; break;
- //move up by 1 char
- case '\r': y -= _scale.y; break;
- //draw char normally
- default:
- putCharRaw(chr, x,y);
- x += _scale.x;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement