Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <utils/font.hpp>
- //a modified version of https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h
- //here, i changed its formatting, and made 16 gradient chars between $10-$20
- //(space included, which itself is a gradient value of 0)
- /*
- for an example of how chars are encoded,
- this is what the bits for char '3' look like in big endian:
- 0b00011110 (0x1E)
- 0b00110011 (0x33)
- 0b00110000 (0x30)
- 0b00011100 (0x1C)
- 0b00110000 (0x30)
- 0b00110011 (0x33)
- 0b00011110 (0x1E)
- 0b00000000 (0x00)
- */
- const Uint8 font8x8_default[1024] = { //128 chars of 8 bytes each = 1024 bytes
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$00 (null)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$01 (start of heading)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$02 (start of text)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$03 (end of text)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$04 (end of transmission)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$05 (enquiry)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$06 (acknowledge)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$07 '\a' (bell)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$08 '\b' (backspace)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$09 '\t' (horizontal tab)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$0A '\n' (new line)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$0B '\v' (vertical tab)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$0C '\f' (new page)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$0D '\r' (carriage return)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$0E (shift out)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$0F (shift in)
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //$10 (gradient value 16)
- 0xFF, 0xFF, 0xEE, 0xFF, 0xFF, 0xFF, 0xEE, 0xFF, //$11 (gradient value 15)
- 0xBB, 0xFF, 0xEE, 0xFF, 0xBB, 0xFF, 0xEE, 0xFF, //$12 (gradient value 14)
- 0xAA, 0xFF, 0xEE, 0xFF, 0xAA, 0xFF, 0xEE, 0xFF, //$13 (gradient value 13)
- 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, //$14 (gradient value 12)
- 0xAA, 0xDD, 0xAA, 0xDD, 0xAA, 0xDD, 0xAA, 0xDD, //$15 (gradient value 11)
- 0xAA, 0xDD, 0xAA, 0x77, 0xAA, 0xDD, 0xAA, 0x77, //$16 (gradient value 10)
- 0xAA, 0xDD, 0xAA, 0x55, 0xAA, 0xDD, 0xAA, 0x55, //$17 (gradient value 9)
- 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, //$18 (gradient value 8)
- 0xAA, 0x44, 0xAA, 0x55, 0xAA, 0x44, 0xAA, 0x55, //$19 (gradient value 7)
- 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11, //$1A (gradient value 6)
- 0xAA, 0x44, 0xAA, 0x00, 0xAA, 0x44, 0xAA, 0x00, //$1B (gradient value 5)
- 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, //$1C (gradient value 4)
- 0xAA, 0x00, 0x88, 0x00, 0xAA, 0x00, 0x88, 0x00, //$1D (gradient value 3)
- 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, //$1E (gradient value 2)
- 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, //$1F (gradient value 1)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$20 ' ' (gradient value 0)
- 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, //$21 '!'
- 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$22 '"' (use \" if inside string)
- 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, //$23 '#'
- 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00, //$24 '$'
- 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00, //$25 '%'
- 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00, //$26 '&'
- 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, //$27 '\'' (use ' if outside char literal)
- 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00, //$28 '('
- 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00, //$29 ')'
- 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, //$2A '*'
- 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00, //$2B '+'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06, //$2C ','
- 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, //$2D '-'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, //$2E '.'
- 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, //$2F '/'
- 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00, //$30 '0'
- 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00, //$31 '1'
- 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00, //$32 '2'
- 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00, //$33 '3'
- 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00, //$34 '4'
- 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00, //$35 '5'
- 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00, //$36 '6'
- 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00, //$37 '7'
- 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00, //$38 '8'
- 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00, //$39 '9'
- 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, //$3A ':'
- 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06, //$3B ';'
- 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00, //$3C '<'
- 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00, //$3D '='
- 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00, //$3E '>'
- 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00, //$3F '?' (or \? to avoid trigraphs)
- 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00, //$40 '@'
- 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00, //$41 'A'
- 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00, //$42 'B'
- 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00, //$43 'C'
- 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00, //$44 'D'
- 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00, //$45 'E'
- 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00, //$46 'F'
- 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00, //$47 'G'
- 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00, //$48 'H'
- 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, //$49 'I'
- 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00, //$4A 'J'
- 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00, //$4B 'K'
- 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00, //$4C 'L'
- 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00, //$4D 'M'
- 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00, //$4E 'N'
- 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00, //$4F 'O'
- 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00, //$50 'P'
- 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00, //$51 'Q'
- 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00, //$52 'R'
- 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00, //$53 'S'
- 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, //$54 'T'
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00, //$55 'U'
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00, //$56 'V'
- 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00, //$57 'W'
- 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00, //$58 'X'
- 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00, //$59 'Y'
- 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00, //$5A 'Z'
- 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00, //$5B '['
- 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, //$5C '\\'
- 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00, //$5D ']'
- 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, //$5E '^'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, //$5F '_'
- 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, //$60 '`'
- 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00, //$61 'a'
- 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00, //$62 'b'
- 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00, //$63 'c'
- 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00, //$64 'd'
- 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00, //$65 'e'
- 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00, //$66 'f'
- 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F, //$67 'g'
- 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00, //$68 'h'
- 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, //$69 'i'
- 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, //$6A 'j'
- 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00, //$6B 'k'
- 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, //$6C 'l'
- 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00, //$6D 'm'
- 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00, //$6E 'n'
- 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00, //$6F 'o'
- 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F, //$70 'p'
- 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78, //$71 'q'
- 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00, //$72 'r'
- 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00, //$73 's'
- 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00, //$74 't'
- 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00, //$75 'u'
- 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00, //$76 'v'
- 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00, //$77 'w'
- 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00, //$78 'x'
- 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F, //$79 'y'
- 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00, //$7A 'z'
- 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00, //$7B '{'
- 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, //$7C '|'
- 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00, //$7D '}'
- 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$7E '~'
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //$7F (indicates transparency)
- };
- font8x8::font8x8(SDL_Renderer* renderer, 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){
- _valid = SDL_FALSE;
- throw SDL_GetError();
- }
- //generate pixel data from font data
- if(SDL_LockSurface(_fontSurface)){ //make sure i have safe access to pixel data
- _freeSurfaceSafely();
- _valid = SDL_FALSE;
- 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 black and white, and create font texture
- _valid = SDL_TRUE; //_valid will be set back to false if setPalette fails
- setPalette( {0x00,0x00,0x00,0xFF}, {0xFF,0xFF,0xFF,0xFF} );
- }
- 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, destinationRect;
- //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)
- destinationRect.x = x;
- destinationRect.y = y;
- destinationRect.w = _scale.x;
- destinationRect.h = _scale.y;
- SDL_RenderCopy(_renderer, _fontTexture, &sourceRect, &destinationRect);
- }
- void font8x8::printRaw(const std::string& txt, int x, int y){
- int startX = x;
- size_t length = txt.length();
- for(size_t i=0; i<length; ++i){
- char chr = txt.at(i);
- if(chr == '\n'){ //on newline, reset x and move y down 1 char
- x = startX;
- y += _scale.y;
- } else { //otherwise draw the char normally
- putCharRaw(chr, x,y);
- x += _scale.x;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement